最近は Windows Containers じゃない Docker Container を弄っていたので、勢いで App Service on Linux 向けに nginx + php-fpm という鉄板な構成でカスタムランタイムを作成しました。
既に shibayan/nginx-php-fpm というイメージ名で Docker Hub に上げてあるので、それを使うとコンテンツをディレクトリにコピーするだけの Dockerfile を作れば動きます。
FROM shibayan/nginx-php-fpm COPY index.php /var/www/html/index.php
index.php にはお馴染みの phpinfo だけ書いておきました。
この Dockerfile をビルドして Docker Hub にプッシュし、App Service で設定すれば終わりです。
実際に作成したイメージをデプロイしました。Server API が FPM になっているのが確認できました。
これだけだと一瞬で終わってしまったので、App Service on Linux について最近調べていたことを簡単にまとめておこうかと思いました。後は作成したイメージについてもう少し説明を書きます。
アーキテクチャについて
そういえば App Service on Linux が Docker Container に対応した話は書いてなかった気がします。アーキテクチャについては公式情報がゼロですが、以下の記事がまとまっていると思います。
Nazim 氏がコメントを書き込んでいるので、大体当たりのようです。軽く基本的な情報をまとめます。
- ホスト OS は Ubuntu 16.04
- ビルトインイメージは Debian 8 ベース (debian:jessie)
- www と scm は別のコンテナで動作している
- ランタイムに .NET Core を指定しても Kudu で dotnet コマンドが叩けない理由がこれ
- /home は www と scm 共通でマウントされている
OS が Ubuntu と Debian のどちらかという話がありましたが、両方というのが正解。他にも今は Docker のイメージを変更すると 503 になったりしますが、今後アップデートで対応されるとかなんとか。
docker コマンドを Kudu から見えるようにすると、コンテナ間のアイソレーションで問題になりそうなので、カスタムデプロイスクリプトで docker build というのは非常に難しそうです。
カスタムイメージを作る
アーキテクチャの話はこれぐらいにして、実際に nginx と php-fpm を使う Docker イメージを作成してみます。調べると良く出てくるのが nginx と php-fpm を別コンテナにする方法ですが、App Service on Linux では Docker Compose は使えないので 1 つのコンテナで両方動かすことにします。
ベースとなるイメージは公式の php-fpm を使いました。確か Debian ベースです。
FROM php:7.0.6-fpm # Install nginx RUN apt-key adv --keyserver hkp://pgp.mit.edu:80 --recv-keys 573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62 \ && echo "deb http://nginx.org/packages/mainline/debian/ jessie nginx" >> /etc/apt/sources.list \ && apt-get update \ && apt-get install -y nginx --no-install-recommends # Install PHP extensions RUN apt-get update \ && apt-get install -y libpng12-dev \ libjpeg-dev \ libpq-dev \ libmcrypt-dev \ libldap2-dev \ libldb-dev \ libicu-dev \ libgmp-dev \ && ln -s /usr/lib/x86_64-linux-gnu/libldap.so /usr/lib/libldap.so \ && ln -s /usr/lib/x86_64-linux-gnu/liblber.so /usr/lib/liblber.so \ && ln -s /usr/include/x86_64-linux-gnu/gmp.h /usr/include/gmp.h \ && rm -rf /var/lib/apt/lists/* \ && docker-php-ext-configure gd --with-png-dir=/usr --with-jpeg-dir=/usr \ && docker-php-ext-install gd \ mysqli \ opcache \ pdo \ pdo_mysql \ pdo_pgsql \ pgsql \ ldap \ intl \ mcrypt \ gmp \ zip \ bcmath \ mbstring \ pcntl # Install Supervisor RUN apt-get update \ && apt-get install -y supervisor \ && mkdir -p /var/log/supervisor # Add configuration COPY default.conf /etc/nginx/conf.d/default.conf COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf EXPOSE 80 CMD ["/usr/bin/supervisord"]
ダラダラと長いですが、やっていることは nginx / php extensions / supervisor のインストールと設定ファイルのコピーだけです。PHP Extension のインストールは公式の Dockerfile を参考にしました。
nginx の設定ファイルは非常にシンプルです。やっていることは FastCGI の設定と REMOTE_ADDR を正しくするための設定ぐらいです。ちゃんと 80 番ポートをリッスンするようにしておきます。
server { listen 80; server_name _; root /var/www/html; index index.php index.html index.htm; charset utf-8; set_real_ip_from 10.0.0.0/8; set_real_ip_from 172.17.0.0/16; real_ip_header X-Forwarded-For; real_ip_recursive on; location / { try_files $uri $uri/ /index.php$is_args$args; } location ~ \.php$ { fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } }
公式の php-fpm イメージをベースに作っているので、9000 番ポートに FastCGI のリクエストを流し込みます。この辺りは特に代わり映えのしない、ありがちな設定です。
最後に Supervisor の設定ファイルです。nginx と php-fpm を立ち上げているだけです。
[supervisord] nodaemon=true [program:php-fpm] command=php-fpm priority=10 [program:nginx] command=nginx -g "daemon off;" priority=5
とりあえず優先順位をつけて php-fpm が先に起動するようにしました。これで docker build すると nginx と php-fpm のベースイメージが完成するので、あとはコンテンツを追加したイメージを作ります。
本来なら App Service のビルトインイメージと同じように /home/site/wwwroot のファイルを使う方法もありますが、今はちょっとしたバグがあるので紹介は止めておきました。直ったら書きます。