MongoDBを3.4→3.6→4.0とアップデートしていった

 祝MongoDB4.0、トランザクションサポート。このブログのデータベースはMongoDB。3.4からバージョンアップをさぼっていたが、この機会に→3.6→4.0へとサクッとやった。サクッとできた。軽い手順メモ。環境はCentOSの7系。レプリカなしのスタンドアロン構成。

検証
 データベースのバージョンアップを行った場合の検証はDockerが活躍。元のデータベースはdumpを取って動作を止め、DockerHubからMongoDB4.0のイメージを落として立ち上げた。そしてdumpをリストア。これでデータベース変更が完了し、自動テストがすべてそのまま通ったので先に進んだ。


3.4→3.6
 公式にある手順に従う。ただしbind_ipなるオプションが追加されている。これはアクセスを受け付けるIPを絞るオプション。最初はローカルのみ受け入れる設定になっている。mongod.confをデータベース起動前にいじって、ワイルドカードとなる0.0.0.0を設定した。いろいろなサーバからアクセスしてるので。


3.6→4.0
 公式にある手順に従う。こっちのバージョン変更は設定はなにもいじらないでいけた。


 Dockerと自動テストのおかげで検証が楽に進んだ。まあ金さえあればマネージドのデータベースを使ってもっと楽ができる。個人の趣味でやるにはマネージドって高いんだけど、開発者が運用に取られて消費する時間を考えると安いと思うような価格設定がされているんじゃあないかというところ。時は金。
comment: 0

MongoDB Atlasを使うのを先送りにした

 MongoDBのマネージドサービスであるMongoDB Atlasの手ごろなプランが出たなーと思って、データを展開して試していた。M2/M5がその手ごろなプラン。


 導入に際して、サーバは三大パブリッククラウドの各リージョンから選べた。だがM2/M5はそこから制限がそこそこあった。まあそこはGCPの台湾リージョンを選んでみた。
 無理だったのは機能の制限。リソースが共有なだけあって、コストが高くつきそうな機能は使えなかった。サーバサイドJSの実行とか。
Atlas M0 (Free Tier), M2, and M5 Limitations
comment: 0

VPSのMongoDBを使っていたが、MongoDB Atlasにデータを移植した

 VPSのOSの管理が面倒なので、PaaSやらなんやらを使ってVPSを避ける手段を模索していた。ただそのなかでコスト面の比較からMongoDBだけはVPSを使ってやっていた。さいきんMongoDB Atlas(MongoDBのDB as a Service)の価格表をふと見たら、いつの間にか月10ドル程度で済むプランが追加されていた。なので使用の検討を始めた。VPSのOSとかセキュリティのためのアップデートから解放されたいので。
 サーバは三大メジャーパブリッククラウドの各リージョンから選べる。ありがたい。ちょっとお高いプランを選べばバックアップも自動化オプションが出てくるが、それはコストがちょっと高かったので、サーバレスで組むことにでもする。
 今回は既存データベースのデータを、ダンプ、リストアでAtlas上に移す。

 まず登録して、フォームをシコシコと埋めていく。フリープランもあるので、使い始めるのにクレジットカードが必須ということはない。フォームを埋めて登録し、フリープランでMongoDBクラスタを作ると、クラウドに実際それを作っている時間を待ったのち、試用できるようになる。



 データベース接続を行うため、設定していく。セキュリティメニュー内にIPホワイトリストがあるが、ぼくは固定IPを持っていないので全部受け入れに。
 あとはユーザとその権限。ここをちゃんとやっておかないと、セキュリティのためにデータベースが使えないのは当然のこと。まあ個人用途なので、一つのユーザに必要な権限をすべて与えた。





 ユーザを作成したら、とりあえずそれでつないでみる。クラスタのOverviewに”CONNECT”というボタンがあるので押してみると、接続方法の選択になる。MongoShellを選んで、自分の環境を選択すると接続文字列が含まれたコマンドが表示される。MongoShellが使える環境でこれを実行する。接続が確立されるはず。メッセージの中に下記のものがあるので、あとでデータを移植するときの接続用に [クラスタのアドレスを表す文字列]を控えておく。
I NETWORK  [thread1] Starting new replica set monitor for [クラスタのアドレスを表す文字列]


 接続したらいじりたいようにいじってみる。

 あとはデータの移植。まず移植したいデータベースのダンプを取る。
mongodump --host foo -u bar -p boo

 ダンプがdumpというディレクトリにまとまっているはず。圧縮されてたら解凍する。ディレクトリdumpで中身を見ると、データベースごとにディレクトリ分けされてデータがまとまっているはず。今回リストアするとき、個人的にデータベースadminは引き継がなくてよかったのでディレクトリを消しておいた。
 リストアを実行する。ディレクトリdumpで下記のコマンド。
mongorestore --ssl --host [さっき控えたクラスタのアドレスを表す文字列] --authenticationDatabase admin --dir=. -u foo --password bar

 これでリストアが実行されるので、終わったらまた接続して中を確認してみるなど。
comment: 0

MongoDBのC#ドライバ(2.4.4)で出たバグとその回避

 このブログのTravisCIで行っているテストがコケた。原因を追っていたら、MongoDBのC#ドライバの2.4.4.にバグがあった。

 データベースからコレクションリストをそのまま取得しようとするとエラーが出る。
var collections = db.ListCollections();


Unhandled Exception: System.FormatException: The GuidRepresentation for the reader is CSharpLegacy, which requires the binary sub type to be UuidLegacy, not UuidStandard.




 ドライバのバージョンが2.5で修正されているらしいが、2.5のリリース日程が見当たらない。Githubのリポジトリを見ても2.4.xまでしかブランチがない。ドライバのバージョンを下げずに今すぐどうにかならんかと。

 もともとListCollectionsでやっていたのは、コレクション一覧を取得してからの、任意の名前のコレクションがそこにあるかの確認。
var collections = DbConnection.db.ListCollections().ToList().Select(c => c["name"].AsString);


 ちょっとコードを変えたらエラーを回避できた。
var filter = new BsonDocument("name", collectionName);

var isExist = DbConnection.db.ListCollections(new ListCollectionsOptions { Filter = filter }).Any();


 もとはコレクションをリストで取ってきて、LINQでふるいをかけて、任意の名前のコレクションがあるかを確認していた。それを、コレクションでリストを取ってくるときにドライバ側で用意されたオプションを使って、ドライバで用意されたもので完結するように書き換えた。
comment: 0

VisualStudioでDockerサポート付きのアプリを作ってCI/CD構築する 最終回

 VisualStudioで作るDockerサポートの付いたWebアプリのCI/CD構築までを進めていく。
 前回にSeleniumを使ったテストを用意した。今回はこのテストをTravisCI上で実行し、その後の自動デプロイまで行う。一通りのファイルが入ったコミットは↓。
https://github.com/hMatoba/DockerAppWithCI/tree/75bf4e201625ad0ae4bfa76f38bfd80acd8b67e3


 TravisCIとGithubの連携は済んでおり、GithubへのプッシュでTravisCIでのビルドまで走るようになっているとする。.travis.ymlはこれから用意する。
.travis.yml

language: csharp
mono: none
dotnet: 2.0.0
dist: trusty
services:
- docker

env:
- DOCKER_COMPOSE_VERSION=1.16.0

install:
- sudo rm /usr/local/bin/docker-compose
- curl -L https://github.com/docker/compose/releases/download/${DOCKER_COMPOSE_VERSION}/docker-compose-`uname -s`-`uname -m` > docker-compose
- chmod +x docker-compose
- sudo mv docker-compose /usr/local/bin
- cd SeleniumTest
- sudo pip install -r requirements.txt
- cd ..

script:
- cd DockerAppWithCI
- dotnet publish DockerAppWithCI.csproj -c Release -o ./obj/Docker/publish
- docker build -t matoba/dockerappwithci:ci .
- cd ..
- docker-compose -f docker-compose.travis.yml config
- docker-compose -f docker-compose.travis.yml build
- docker-compose -f docker-compose.travis.yml up -d
- sleep 10
- cd SeleniumTest
- python setup.py test
- cd ..

after_success:
- docker tag matoba/dockerappwithci:ci matoba/dockerappwithci:latest
- docker login -u="${DOCKER_USERNAME}" -p="${DOCKER_PASSWORD}"
- docker push matoba/dockerappwithci:latest

matrix:
fast_finish: true


 installの項で、docker composeやseleniumテストに必要なものをインストールしている。
 scriptの項ではまず、Webアプリプロジェクトの発行を行っている。Webアプリを他環境にもっていっても実行可能な状態で出力してくれるのがdotnetのpublishコマンド。
https://docs.microsoft.com/ja-jp/dotnet/core/tools/dotnet-publish?tabs=netcore2x
 Webアプリがdotnetコマンドで発行されたら、それを入れたDockerイメージをビルドする。そしてcomposeでWebアプリコンテナを含めた、テスト一連に必要なコンテナの起動を行う。TravisCIでのテスト用に、docker-compose.travis.ymlというファイルを用意して、これをターゲットにcomposeコマンドを実行している。webappコンテナで使うイメージは直前にビルドしてあるのでそれを使う。あとのリバースプロキシ、Selenium、MongoDBのコンテナは開発環境と同様。
docker-compose.travis.yml

version: '3'

services:
webapp:
image: matoba/dockerappwithci:ci
front:
image: matoba/ssldevenv
ports:
- "443:443"
selenium:
image: selenium/standalone-chrome:3.4
ports:
- "4444:4444"
mongo:
image: mongo
ports:
- "27017:27017"

 これを使ってcompose upするが、ちょっと待ってやらないとコンテナの準備が完了しない。そのためcompose upの直後に10秒ほどsleepを入れてある。sleepが終わったら、開発環境でも行っていたSeleniumテストが走る。これに成功すればその後のafter_successの項が実行される。

 ここでデプロイ先、本番環境について。今回はAzureのWeb App for Containersを使う。AzureでWeb App for Containersを作ると、中のオプションからWeb HookのURLが取ってこれる。これをメモしておく。


 次にDocker Hubへ行く。そしてアプリに使うイメージのリポジトリを選択、あるいはまだイメージを一度もプッシュしていなければリポジトリを作る。
 リポジトリのオプションでWeb Hook URLを入れられるようになっている。ここにさきほどメモしたURLを入れる。これでDocker Hubへのイメージ更新が、Web App for Containersへプッシュされるようになる。


 TravisCIへもどる。.travis.ymlについて。after_successではDocker Hubへ、作成されたアプリイメージのプッシュを行っている。${DOCKER_USERNAME}と${DOCKER_PASSWORD}はTravisCIで環境変数として用意しておく。

これでDokcer Hubへのプッシュが行われる。


 上記の動作をする.travis.ymlと、docker-compose.travis.ymlを用意し、Githubへプッシュする。使っているコンテナの多さなどから五分弱ぐらいかかるかもしれないが、自動テストが行われ、テストにパスすればアプリは自動でデプロイされる。


 VisualStudioで作るDockerサポート付きのWebアプリのCI/CD構築ができた。ぼくはこの手順でAzureとは別のサービスを使って、このブログをCI/CDのもとに機能追加をしながら運用している。
https://github.com/hMatoba/tetsujin

 ASP.NET Core MVCのアプリでCI/CDを構築した。開発は今回はWindows上で行ったが、公式ではVSCodeを使ってLinuxやMac上で行う説明がある。ビルド、テスト、デプロイはTravisCI上で行っており、UbuntuやDebianなどのメジャーなディストロを使っている。Github、TravisCI、DockerコンテナホスティングサービスのHyper.shの一連の連携も難なく取れている。C#やそのまわりのコンパイルのツールなどもオープンソースになっている。ベンダーロックイン?なにそれ。
 もうC#はWindowsだけじゃないんだなーというところ。
comment: 0