App Service on Linux 向けとしてですが、Kudu の Mono 対応が進んでいたので Azure 以外の Linux 環境でも動くのではないかと思ったので、手軽な ConoHa を使って試してみました。
そしてついでなので、ASP.NET Core アプリケーションをデプロイするところまで作ってみました。構成は以下のように非常にシンプルですが、地味にめんどくさかったです。
- リバースプロキシ (nginx)
- ASP.NET Core アプリケーション
- Kudu (FastCGI + nginx)
Kudu を動かす部分は App Service on Linux では Apache 2.4 と mod_mono を使っていますが、リポジトリをプッシュする時に問題が出るので nginx と FastCGI を使うように変えました。
Docker Compose の定義を出した方が分かりやすそうなので、貼り付けておきます。
version: '2' services: proxy: build: ./proxy restart: always ports: - "80:80" aspnetcore: build: ./aspnetcore restart: always depends_on: - "proxy" volumes: - "/var/www/home:/home" kudu: build: ./kudu restart: always ports: - "8080:80" volumes: - "/var/www/home:/home" environment: - WEBSITE_SITE_NAME=conoha - KUDU_RUN_USER=conoha
作成した Dockerfile や設定などは GitHub で公開しているので省略します。
/var/www/home を作成しておいて、コンテナでは /home としてマウントします。この home ディレクトリの構成は App Service と同じように作成しておきます。
最低限 wwwroot と LogFiles があれば問題なさそうです。権限周りも一緒に変えておきます。
mkdir -p /var/www/home/site/wwwroot mkdir -p /var/www/home/LogFiles chown -R nobody:nogroup /var/www/home chmod -R 777 /var/www/home
このリポジトリを ConoHa で作成した Ubuntu 16.04 のサーバーに持っていって、イメージのビルドと起動を行います。当然ながら Docker と Dokcer Compose が必要です。
docker-compose.yml があるディレクトリで docker-compose コマンドを叩くだけです。
docker-compose build
docker-compose up -d
これだけで必要なコンテナが全て起動します。書き忘れてましたが 80 と 8080 は開放しておきます。
ちなみに nginx と fastcgi-mono-server4 を立ち上げるために supervisor を使っています。
起動したか確認するために、まず Kudu にアクセスしてみます。IP アドレスとポート番号で見れます。
この時点で Kudu の LocalGit 機能が使えるようになっているので、Source control info API から Git URL を確認できます。ポート番号が入っていないですが、この辺りは対応がめんどくさそうなので放置です。
余談ですが /deploy の URL を GitHub に Webhook として登録すると、GitHub への git push 時に自動でデプロイを実行させることもできます。App Service と全く同じですね。
git clone したリポジトリに対してファイルを追加して git push すると、App Service と同じように KuduScript によってデプロイスクリプトが作成されて、KuduSync で wwwroot にファイルがコピーされます。
ASP.NET Core アプリケーションを実行するためには、dotnet コマンドを使ってビルドしないといけないので、カスタムデプロイスクリプトを追加して対応しました。以下のような感じです。
# 1. Restore nuget packages dotnet restore # 2. Build and publish dotnet publish "src/WebApplication" --output "$DEPLOYMENT_TEMP" --configuration Release # 3. KuduSync if [[ "$IN_PLACE_DEPLOYMENT" -ne "1" ]]; then "$KUDU_SYNC_CMD" -v 50 -f "$DEPLOYMENT_TEMP" -t "$DEPLOYMENT_TARGET" -n "$NEXT_MANIFEST_PATH" -p "$PREVIOUS_MANIFEST_PATH" -i ".git;.hg;.deployment;deploy.sh" exitWithMessageOnError "Kudu Sync failed" fi
KuduScript が bash と ASP.NET Core の組み合わせに対応していないので、プロジェクトのパスを決め打ちにしています。本来なら KuduScript によって自動的に決定される部分です。
実際に git push してみると、ちゃんと dotnet restore と publish が走っていることが確認できます。
本来ならデプロイスクリプトで Docker のイメージを作成して、それを起動するべきなんでしょうが、コンテナの入れ替えがめんどくさそうだったので App Service と同じように /home/site/wwwroot にビルド済みのアプリケーションをコピーする形にしました。
そして aspnetcore コンテナが /home/site/wwwroot に置かれたアプリケーションを実行する形になっています。今の App Service 同じような仕組みで割と単純に出来ました。
これで nginx にアクセスすると ASP.NET Core で作成したページが返ってきます。
アプリケーションを修正する場合も git push すればビルドされて wwwroot にコピーされますが、aspnetcore コンテナの再起動が必要なので少し面倒です。Kudu のコンテナから docker を使えるようにすると restart が簡単ですが、それは今後の課題ということにします。