最近は仕事で Visual Studio Team Services と Web App for Container を使っていましたが、地味にデプロイ周りで苦労をしたので軽くまとめておきます。
デプロイだけでは面白くないので、ASP.NET Core アプリケーションのビルドから行ってみます。Web App for Container には VSTS を使った CD を設定する機能がありますが、実際に試してみたところ中途半端な感じだったので、手動でビルドタスクを組みました。
VSTS で必要なものは Docker でタスクを検索すると出てきます。
そして ASP.NET Core アプリケーションのビルドに必要なものは、Visual Studio 2017 で Docker サポートを追加すると全て追加されるので、準備することはあまりありません。
VSTS には .NET Core のビルドを行うタスクもありますが、現在のビルドワーカーに入ってるランタイムバージョンなどを調べるのが面倒だったので、Docker Image を使ってビルドを行います。
予めリポジトリを作成して、ASP.NET Core アプリケーションのソースがプッシュされている前提で進めます。あとビルドタスクはテンプレートを使いません。
ASP.NET Core アプリケーションのビルド
Visual Studio 2017 で Docker サポートを有効にしてプロジェクトを作ると、Docker Compose を利用したビルド用の yaml がいくつか追加されます。ちゃんと CI 用の定義も用意されているので、これを使います。
Docker Compose がインストールされている環境であれば、CI 用の定義を読み込んで docker-compose up すればアプリケーションのビルドが完了します。非常にシンプルで良いですね。
出力先は /obj/Docker/publish 固定になっていますが、ここは絶対に変更してはいけないです。
version: '3' services: ci-build: image: microsoft/aspnetcore-build:1.0-2.0 volumes: - .:/src working_dir: /src command: /bin/bash -c "dotnet restore ./WebApplication20.sln && dotnet publish ./WebApplication20.sln -c Release -o ./obj/Docker/publish"
ここで分かりにくいのが microsoft/aspnetcore-build:1.0-2.0 というタグのイメージを使わないと Visual Studio の Docker 向け SDK がインストールされておらず、ビルド時にエラーとなってしまうので注意。
素直に Visual Studio 2017 で生成されたまま使うのが正解という話でした。
VSTS では Docker Compose タスクを追加して、Action を "Run service images" に、Docker Compose File を docker-compose.ci.build.yml に変更するだけです。
ルートにあるので ** は必要ないですが、あっても害はないので追加したままにしてます。
Docker Image のビルドと ACR へのプッシュ
アプリケーションのビルド後は Docker Image を作成します。デフォルトで生成されている Dockerfile は、ちゃんと Docker Compose を使ってビルドされた前提のパスになっているので簡単です。
FROM microsoft/aspnetcore:2.0 ARG source WORKDIR /app EXPOSE 80 COPY ${source:-obj/Docker/publish} . ENTRYPOINT ["dotnet", "WebApplication20.dll"]
VSTS では Docker タスクを追加して、Action を "Build an image" にするだけです。Dockerfile のパスは最初から適切な値になっているはずなので、特に弄る必要はありません。
Docker Image のビルド後はそれを ACR にプッシュする必要がありますが、これも Docker タスクを追加して Action を "Push an Image" に変えるだけで完了です。GUI での設定なので、あまりやることがないですね。
App Service へのデプロイ
ASP.NET Core アプリケーションが含まれている Docker Image はここまでで ACR までプッシュされているはずなので、最後は Web App for Container にデプロイを行います。
VSTS には非常に便利な Azure App Service Deploy というタスクがあるので、これを利用します。説明文をよく読むと Linux にも対応していると書いてありました。
App Service on Linux では Staging スロットを使ってスワップする運用が必須なので、デプロイ先のスロットの選択が簡単に行えるのは非常に良いです
CircleCI で同じようにデプロイした時はサービスプリンシパルを用意したり、Azure CLI をインストールしたりと手間がかかりましたが、VSTS だとポチポチと設定すれば終わるのが楽ですね。
今回作成した VSTS のビルド定義は上のようになりました。ビルドからデプロイに必要なのは 4 ステップだけというシンプルさです。App Service へのデプロイタスクのおかげですね。
ビルドを行いデプロイを確認
最後にちゃんとビルドを実行して、Web App for Container にデプロイされることを確認しておきました。
VSTS は Docker Image をキャッシュしてくれないようで、アプリケーションのビルドに地味に時間がかかりましたが、それでも 3,4 分で完了しました。aspnetcore-build とかは予め持っておいて欲しいですね。
Azure Portal で staging スロットにデプロイされている Docker Image を確認すると、ちゃんとビルドされたバージョンに切り替わっていました。
ここで ACR 扱いになっていない場合は、ACR の Admin User が有効になっていないか、Web App に ACR の情報が設定されていないかのどちらかです。予め設定しておく必要があります。
おまけ:自動でスワップを行って本番リリース
VSTS には App Service のスロットをスワップするタスクもあるので、これを使えば新しい Docker Image をデプロイした後、自動的にスワップを実行してリリースすることも出来ます。
Source slot を指定してビルドすれば、Production とスワップされて最新のビルドがリリースされます。
Windows 版の App Service では Auto Swap という機能がありましたが、同じことを Web App for Container でも実現できます。癖のあるデプロイ周りですが、便利に使っていきましょう。