Azure Web Apps and Linux/Containers について知るべきこと - 日本語意訳

# この記事について
この記事は、[Things You Should Know: Web Apps and Linux](https://blogs.msdn.microsoft.com/waws/2017/09/08/things-you-should-know-web-apps-and-linux/) という記事を要約＆意訳したもの。
App Service on Linux / Web App for Containers について、使い始めてチュートリアルを終えたあたりから気になってくるポイントがまとまっている。
元記事のヘッダ見出しごとになるべく短め（省略含む）に書いているため、内容詳細はぜひ元記事を参照いただきたい。

# 本文
Azure App Service on Linux は、Microsoft が提供するランタイムスタック一式でWeb App を利用できる。 
Web App for Containers は、Azure Container Registry や Docker Hub、またはプライベートなレジストリ上の独自のDockerコンテナを利用することができる。

* <img src="https://qiita-image-store.s3.amazonaws.com/0/29416/18497bda-819a-6f77-1ef0-8ee11270bc70.png" width="25" /> Azure App Service on Linux に適用
* <img src="https://qiita-image-store.s3.amazonaws.com/0/29416/812e67a2-91d9-5f38-08c2-a53e8337a8e5.png" width="25" /> Web App for Containers に適用

## If you need info, check the FAQ.
<img src="https://qiita-image-store.s3.amazonaws.com/0/29416/18497bda-819a-6f77-1ef0-8ee11270bc70.png" width="25" /> <img src="https://qiita-image-store.s3.amazonaws.com/0/29416/812e67a2-91d9-5f38-08c2-a53e8337a8e5.png" width="25" />
もし情報が必要ならば、まずFAQを確認すること。
[FAQ for Azure App Service on Linux and Web App for Containers](https://docs.microsoft.com/en-us/azure/app-service/containers/app-service-linux-faq) （訳者注：日本語ページは [こちら](https://docs.microsoft.com/ja-jp/azure/app-service/containers/app-service-linux-faq) ）
このFAQは素晴らしいコンテンツで、機能の更新なども定期的に反映している。

## If your site doesn't start, check the Docker log.
<img src="https://qiita-image-store.s3.amazonaws.com/0/29416/812e67a2-91d9-5f38-08c2-a53e8337a8e5.png" width="25" />
もし起動しなかったら、まず /LogFiles にある docker log を見て。
Kudu の Bash コンソールか、FTP クライアント、API からダウンロードすることもできる。
FTP クライアントを使うときは、ファイルロックのエラーに気を付けること。その時は API からダウンロードするのがいい。

## You can discover and download the latest Docker logs using Kudu.
<img src="https://qiita-image-store.s3.amazonaws.com/0/29416/812e67a2-91d9-5f38-08c2-a53e8337a8e5.png" width="25" />
最新の Docker ログを JSON 形式で見るには、このURLが使える。
`https://[sitename].scm.azurewebsites.net/api/logs/docker`
Kudu に行ったあと、"/api/logs/docker" をつけるのが簡単。
Zip でダウンロードしたければ、"/api/logs/docker/zip" をつけて。

## You shouldn't install components using SSH because they won't persist.
<img src="https://qiita-image-store.s3.amazonaws.com/0/29416/18497bda-819a-6f77-1ef0-8ee11270bc70.png" width="25" /> <img src="https://qiita-image-store.s3.amazonaws.com/0/29416/812e67a2-91d9-5f38-08c2-a53e8337a8e5.png" width="25" />
SSH でコンポーネントをインストールできるのだけれど、その方法では再起動すると無くなってしまう。これはまさに Docker の挙動そのもので、サイトがスタートしたときに、Docker イメージを実行して、Docker コンテナを作るから。
もし特定のコンポーネントをインストールしたいのなら、Dockerfile 上でやること。Docker イメージの中に含まれることになるから。どうやるかは、[このドキュメント](https://docs.microsoft.com/en-us/azure/app-service/containers/tutorial-custom-docker-image) を見て。（訳者注：日本語ページは [こちら](https://docs.microsoft.com/ja-jp/azure/app-service/containers/tutorial-custom-docker-image) ）

## If your container takes a long time to start, increase the start time limit.
<img src="https://qiita-image-store.s3.amazonaws.com/0/29416/812e67a2-91d9-5f38-08c2-a53e8337a8e5.png" width="25" />
コンテナ起動に長時間かかるなら、start time limit を増やすこと。
コンテナを起動したとき、インスタンスの開始と初期化の間、待つことになる。
コンテナを実行して、HTTP トラフィックを受ける準備ができているか確認するための ping に応答があると起動が成功したとみなす。
230 秒待って、それ以内に成功しないと、何か問題ありとして、コンテナを停止する。
230 秒の待ち時間を 600 秒まで増やすことができる。その設定をするためには、WEBSITES_CONTAINER_START_TIME_LIMIT というアプリケーション設定を追加する。
（元記事に画面キャプチャあり）

## Check the return code from "docker run" if your site doesn't start.
<img src="https://qiita-image-store.s3.amazonaws.com/0/29416/812e67a2-91d9-5f38-08c2-a53e8337a8e5.png" width="25" />
もしサイトが起動しなければ、まずは、 "docker run" の戻り値を確認するのがよい。上記のとおり、HTTPリクエストに応答するまで、"started" 扱いにならない。
Docker ログの一部はこんな感じ。

```
2017-09-14 19:26:22.494 INFO  - Starting container for site
2017-09-14 19:26:22.496 INFO  - docker run -d -p 52879:80 --name customer-webapp . . .
2017-09-14 19:26:24.271 INFO  - docker run returned: STDOUT>> c73ac7c0d7d2c1726d7a95929e591703d7c39eb7e7f314210ad5b4064f433762
. . .
2017-09-14T19:26:34.628607412Z { engine: 'joenode', port: '3000', pid: 5 }
2017-09-14 19:30:14.428 ERROR - Container customer-webapp_0 for site customer-webapp did not start within expected time limit. Elapsed time = 230.0443067 sec>
```

だいぶ端折っているけど、"docker run" の2秒後に、長い16進の文字列で戻り値があることがわかると思う。（3行目）この文字列がコンテナの一意ID。コンテナの一意IDがあるということは、そのコンテナが実際に起動したということ。でもログの最後には、制限時間内にコンテナが起動しなかった、とある。
・・・
この問題の解決策は２つ。
１．3000 ポートを開放するために、Dockerfileで EXPOSE 命令を使う
２．アプリケーション設定 WEBSITES_PORT で "3000" を設定する

## The Bash console in Advanced Tools is a different Docker container.
<img src="https://qiita-image-store.s3.amazonaws.com/0/29416/18497bda-819a-6f77-1ef0-8ee11270bc70.png" width="25" /> <img src="https://qiita-image-store.s3.amazonaws.com/0/29416/812e67a2-91d9-5f38-08c2-a53e8337a8e5.png" width="25" />
Kudu で Bash コンソールを提供しているけど、これは Kudu の Docker コンテナ内で実行されていることが重要。これはアプリケーションが実行されているコンテナではない。なので、そこで見えているファイルやディレクトリは、アプリケーションへは反映されない。唯一の例外は、/home ディレクトリ。これはデフォルトで Azure Storage からマウントされていて、Kudo コンテナ上と アプリケーションコンテナ上で同じ場所。

## If you're persisting files, only the /home directory is persisted.
<img src="https://qiita-image-store.s3.amazonaws.com/0/29416/812e67a2-91d9-5f38-08c2-a53e8337a8e5.png" width="25" />
ファイルを永続化するなら、/home ディレクトリだけ。
デフォルトではファイルは永続化されない。ただし、もし永続化する必要があれば、App Service Storage で可能になる。（参考： [You can enable and disable storage persistence with an app setting](
https://blogs.msdn.microsoft.com/waws/2017/09/08/things-you-should-know-web-apps-and-linux/#NoStorage)） これをONにすると、/home ディレクトリが Azure Storage にマウントされる。これで再起動しても /home ディレクトリとそのサブディレクトリに保存されているファイルは永続化される。

* npm や apt など、アプリケーション起動後にコンソールからインストールする類のものは、再起動後にインストールされたものは無くなってしまう。
* /home ディレクトリ以外にファイルを保存すると、再起動後にそれらのファイルは無くなってしまう。
拡張や他のコンポーネントが必要であれば、Dockerfile でインストールすること。そしてファイルを永続化する必要があれば、それを /home ディレクトリ配下に書き込むこと。

独自コンテナを作るためのさらなる情報は、[このドキュメント](https://docs.microsoft.com/en-us/azure/app-service-web/app-service-linux-using-custom-docker-image) を見て。（訳者注：日本語ページは [こちら](https://docs.microsoft.com/ja-jp/azure/app-service/containers/tutorial-custom-docker-image) ）

## If you're persisting files, don't copy data to /home during build.
<img src="https://qiita-image-store.s3.amazonaws.com/0/29416/812e67a2-91d9-5f38-08c2-a53e8337a8e5.png" width="25" />
もしファイル永続化するなら、ビルド中に /home にコピーしないこと。
/home ディレクトリにあるものは全て、Azure Storage 上から上書きされることを理解することが重要。  （まっさらな新規のアプリケーションは、/home ディレクトリは空になる）
Docker イメージのビルドフェーズでデータを /home ディレクトリにコピーすると、Docker コンテナが起動するときにそのデータが消える。つまり、ビルドフェーズでファイルシステムに書き込むデータは全て /home ディレクトリ以外の場所に書き込まれるべき。

## You can enable and disable storage persistence with an app setting.
<img src="https://qiita-image-store.s3.amazonaws.com/0/29416/812e67a2-91d9-5f38-08c2-a53e8337a8e5.png" width="25" />
WEBSITES_ENABLE_APP_SERVICE_STORAGE というアプリケーション設定で、/home ディレクトリを Azure Storage にマップするかどうか制御できる。永続化される必要があるなら、これを "true" に設定すること。もしファイル永続化が不要なら "false"。
注意： App Service Storage が有効でなければ、 /home のファイルはインスタンスをまたいで永続化されない。再起動も同様。

## You can now force SSL using the "HTTPS Only" option in the Azure portal.
<img src="https://qiita-image-store.s3.amazonaws.com/0/29416/18497bda-819a-6f77-1ef0-8ee11270bc70.png" width="25" /> <img src="https://qiita-image-store.s3.amazonaws.com/0/29416/812e67a2-91d9-5f38-08c2-a53e8337a8e5.png" width="25" />
"HTTPS Only" オプションが Azure Portal 上にある。
使う際の詳細は[このドキュメント](https://docs.microsoft.com/en-us/azure/app-service/app-service-web-tutorial-custom-ssl)を参考にすること。（訳者注：日本語ページは [こちら](https://docs.microsoft.com/ja-jp/azure/app-service/app-service-web-tutorial-custom-ssl) ）

## You don't need (and should not have) SSL support in your app.
<img src="https://qiita-image-store.s3.amazonaws.com/0/29416/18497bda-819a-6f77-1ef0-8ee11270bc70.png" width="25" /> <img src="https://qiita-image-store.s3.amazonaws.com/0/29416/812e67a2-91d9-5f38-08c2-a53e8337a8e5.png" width="25" />
SSL サポートはアプリケーション内で不要。（すべきでない）
上述のとおり、フロントエンドで SSL は terminate される。つまり、SSLリクエストは Web Appのアプリケーションまで要求されない。これのいい点は、それぞれのアプリケーション内で SSLをサポートする必要がないこと。また上述のとおり、SSL terminate されるフロントエンドは Azure のデータセンター内であるということも重要である。

## To use SSH, your Docker image needs special sauce.
<img src="https://qiita-image-store.s3.amazonaws.com/0/29416/812e67a2-91d9-5f38-08c2-a53e8337a8e5.png" width="25" />
SSH を使うためには、Docker イメージで特別なひと手間が必要。
SSHを提供しているのだけど、カスタムコンテナを使っている際は、追加でいくつかの手順が必要。必要なステップ全ては [ここ](https://docs.microsoft.com/en-us/azure/app-service-web/app-service-linux-ssh-support#ssh-support-with-custom-docker-images) に書かれている。（訳者注：日本語ページは [こちら](https://docs.microsoft.com/ja-jp/azure/app-service/containers/app-service-linux-ssh-support#ssh-support-with-custom-docker-images) ）


## You can only expose one port to the outside world.
<img src="https://qiita-image-store.s3.amazonaws.com/0/29416/812e67a2-91d9-5f38-08c2-a53e8337a8e5.png" width="25" />
外のネットワークに出れるのは今のところ1つのポートだけ。つまり、一つのポートでHTTPリクエストだけをリッスンできるということ。それでも複数ポートが必要なアプリケーションはある。例えば、一つのポートはアプリケーションへのリクエスト用、ほかのポートでダッシュボードや管理ポータル用に使ったり。今日現在では、Web App for Containers でそのような設定はできない。
どのポートがコンテナにバインドするか検知するように試みているが、それは アプリケーション設定の WEBSITES_PORT で任意の値に設定することができる。

## If a feature is disabled in the portal, it's not available on Linux.
<img src="https://qiita-image-store.s3.amazonaws.com/0/29416/18497bda-819a-6f77-1ef0-8ee11270bc70.png" width="25" /> <img src="https://qiita-image-store.s3.amazonaws.com/0/29416/812e67a2-91d9-5f38-08c2-a53e8337a8e5.png" width="25" />
もしAzure ポータル上で機能が利用不可になっていたら、それはLinux の機能として利用できない。
リッチな機能群があるが、現時点では全ての機能が Linux アプリケーションで利用可能であるわけではない。ポータル上ではメニューがグレーアウトされている。

## Don't use df to find your disk space usage.
<img src="https://qiita-image-store.s3.amazonaws.com/0/29416/18497bda-819a-6f77-1ef0-8ee11270bc70.png" width="25" /> <img src="https://qiita-image-store.s3.amazonaws.com/0/29416/812e67a2-91d9-5f38-08c2-a53e8337a8e5.png" width="25" />
ディスクスペース使用量を見るために、df コマンドを使わないこと。
 "df" コマンドを使っても、思ったより役に立たないことに気付くはず。
/home ディレクトリにファイルを永続化しているとして、価格帯によって容量クォータがあるが、"df" で見えるディスクスペースはそのクォータを反映していない。ディスク使用量を見たければ、Web Appメニューのクォータ (英語メニューではQuotas)、App Service Plan メニューのファイルシステムストレージ（英語メニューではFile System Storage）、または REST API を使うこと。


## To prevent down-time when you update your code, use Continuous Deployment.
<img src="https://qiita-image-store.s3.amazonaws.com/0/29416/812e67a2-91d9-5f38-08c2-a53e8337a8e5.png" width="25" />
コードを変更したときのダウンタイムを回避するためには、CDを使うこと。
コードを更新するとき、新規Dockerイメージをプッシュして、その変更が効くように手動で再起動すると、新規イメージをプルしてコンテナをスタートする間、多少のダウンタイムが発生してしまう。これは継続的デプロイ機能を使って回避することができる。
継続的デプロイを使うと、新規Dockerイメージをレジストリにプッシュしたときに、Web App for Containers が自動的に変更を適用する。イメージをプルして、コンテナを起動して、スイッチする前にその新しいコンテナがHTTPリクエストを受け付ける状態になるまで待つ。その間、古いイメージがリクエストをさばき続ける。
もっと詳しい情報が知りたければ、[ドキュメント](https://docs.microsoft.com/en-us/azure/app-service/containers/app-service-linux-ci-cd)へ。（日本語ページは [こちら](https://docs.microsoft.com/ja-jp/azure/app-service/containers/app-service-linux-ci-cd) )

## If you don't see a feature you want, you can request the feature.
<img src="https://qiita-image-store.s3.amazonaws.com/0/29416/18497bda-819a-6f77-1ef0-8ee11270bc70.png" width="25" /> <img src="https://qiita-image-store.s3.amazonaws.com/0/29416/812e67a2-91d9-5f38-08c2-a53e8337a8e5.png" width="25" />
欲しい機能がなければ、自由に [Web Apps feedback フォーラム](http://aka.ms/webapps-uservoice) へ。タイトルに、"[Linux]" というの文言を入れるのを忘れずに。 　

## If you're deploying using Web Deploy, set WEBSITE_WEBDEPLOY_USE_SCM to false.
<img src="https://qiita-image-store.s3.amazonaws.com/0/29416/18497bda-819a-6f77-1ef0-8ee11270bc70.png" width="25" /> <img src="https://qiita-image-store.s3.amazonaws.com/0/29416/812e67a2-91d9-5f38-08c2-a53e8337a8e5.png" width="25" />
Web Deploy を使ってデプロイするなら、 WEBSITE_WEBDEPLOY_USE_SCM を false にセットすること。
Web App for Linux/Container へデプロイするために Visual Studioを使うことができる。けれどもこれをするときは、そのエンドポイントは Kudu コンテナではないようにしたい。この設定をするためには、アプリケーション設定で WEBSITE_WEBDEPLOY_USE_SCM という名前で false をセットすること。

## App Settings are injected into your app as environment variables at runtime.
<img src="https://qiita-image-store.s3.amazonaws.com/0/29416/18497bda-819a-6f77-1ef0-8ee11270bc70.png" width="25" /> <img src="https://qiita-image-store.s3.amazonaws.com/0/29416/812e67a2-91d9-5f38-08c2-a53e8337a8e5.png" width="25" />
アプリケーション設定は実行時に設定される。
環境変数をセットする必要があれば、シンプルにAzure ポータルのアプリケーション設定で追加する。アプリケーションが実行されたとき、その設定は自動的に環境変数としてプロセスに挿入される。


## Some characters may be stripped out of environment variables.
<img src="https://qiita-image-store.s3.amazonaws.com/0/29416/18497bda-819a-6f77-1ef0-8ee11270bc70.png" width="25" /> <img src="https://qiita-image-store.s3.amazonaws.com/0/29416/812e67a2-91d9-5f38-08c2-a53e8337a8e5.png" width="25" />
環境変数には、alpha-numeric 文字列だけが許されている。そのほかの文字は実行時に取り除かれる。[FAQ](https://docs.microsoft.com/en-us/azure/app-service/containers/app-service-linux-faq#other-questions)にもこの情報あり。（訳者注：日本語ページは [こちら](https://docs.microsoft.com/ja-jp/azure/app-service/containers/app-service-linux-faq#other-questions) ）

## Your environment variables won't appear when you SSH to your container.
<img src="https://qiita-image-store.s3.amazonaws.com/0/29416/18497bda-819a-6f77-1ef0-8ee11270bc70.png" width="25" /> <img src="https://qiita-image-store.s3.amazonaws.com/0/29416/812e67a2-91d9-5f38-08c2-a53e8337a8e5.png" width="25" />
設定した環境変数は、コンテナへ SSH しても見れない。これは、SSH コンソールが、Docker コンテナと同じ場所にないから。
アプリケーション設定が環境変数に引き継がれていることを確認したいのなら、Kudu の Bash コンソールを使うこと。

## If you change your Docker container, it may take a minute or so for it to take effect.
<img src="https://qiita-image-store.s3.amazonaws.com/0/29416/812e67a2-91d9-5f38-08c2-a53e8337a8e5.png" width="25" />
Docker コンテナ設定を異なるコンテナに変更して、Save をクリックすると、新しいコンテナが見えるまで、しばらく時間がかかる。新しいコンテナが pull されて起動するまで、リクエストは古いコンテナのほうへ行く。新しいコンテナが起動してリクエストを受ける準備ができたときに初めてリクエストが新しいほうへ送られる。
新しいサイトが実行されているか確認するいい方法は、Kuduの "site up time" を見ること。新しいコンテナが起動して実行されると、Kudu は再起動する。Kudu の再起動が確認できたら、新しいコンテナは準備できているはず。
（元記事に画面キャプチャあり）

## Set your default document in a Node.js app using JavaScript.
<img src="https://qiita-image-store.s3.amazonaws.com/0/29416/18497bda-819a-6f77-1ef0-8ee11270bc70.png" width="25" /> <img src="https://qiita-image-store.s3.amazonaws.com/0/29416/812e67a2-91d9-5f38-08c2-a53e8337a8e5.png" width="25" />
Node.js アプリケーションを作るとき、デフォルトでは、hostingstart.html を使おうとする。デフォルトドキュメントを設定するには、JavaScriptファイルを使う。index.js ファイルをルートフォルダに作って、以下の内容とする。

```js
var express = require('express');
var server = express();
var options = {
index: 'index.html'
};
server.use('/', express.static('/home/site/wwwroot', options));
server.listen(process.env.PORT);
```

これで index.html がデフォルトドキュメントになるよう設定できる。

## Custom images are stored on disk unless a worker change happens.
<img src="https://qiita-image-store.s3.amazonaws.com/0/29416/812e67a2-91d9-5f38-08c2-a53e8337a8e5.png" width="25" />
ワーカーが変更するまで、カスタムイメージはディスクに保存される。
初回は "docker pull" されて、全てのレイヤに pull される。これらのレイヤは、まさに Docker をオンプレで使ったときと同じようにディスクに保存される。サイトが再起動した後に "docker pull" するときは、変更があったレイヤだけ pull する。変更がなければ、単にディスク上のものを使う。
何らかの理由でワーカーを変更すると、全てのレイヤをもう一度 pull する。ワーカーが変わるのは、例えば、スケールアップ/ダウンや追加のワーカーをスケールアウトしたとき。レアケースとして、スケール操作をしなくてもワーカーが変わることがあるが、これはごくまれなケース。