どうも、若松です。
前回はLaravelをDockerで起動し、イメージを軽量化するところまで行いました。
https://cloudpack.media/48190
今回は、php artisan
でのサーバ起動ではなく、Nginx+php-fpmでLaravelを表示するところまでを行います。
設定
ディレクトリ構造
docker/ ├─ docker-compose.yml ├─ nginx/ | ├─ Dockerfile | └─ default.conf └─ laravel/ └─ Dockerfile
docker-compose.yml
version: '2' services: nginx: image: nginx ports: - "80:80" laravel: image: laravel
Dockerfile(nginx)
FROM nginx:1.17-alpine # ローカルから設定ファイルをコピー COPY default.conf /etc/nginx/conf.d/default.conf
default.conf(nginx)
server { listen 80; server_name localhost; location / { # ドキュメントルート設定 root /var/www/laravel/public; fastcgi_split_path_info ^(.+\.(?:php|phar))(/.*)$; fastcgi_intercept_errors on; fastcgi_index index.php; include fastcgi_params; # FastCGIの向き先をLaravelコンテナに設定 fastcgi_pass laravel:9000; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param PATH_INFO $fastcgi_path_info; fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info; } error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/html; } }
Dockerfile(laravel)
FROM amazonlinux:2 as vender # PHPインストール RUN amazon-linux-extras install -y php7.3 RUN yum install -y php-pecl-zip php-mbstring php-dom # Composerインストール RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" RUN php -r "if (hash_file('sha384', 'composer-setup.php') === '48e3236262b34d30969dca3c37281b3b4bbe3221bda826ac6a9a62d6444cdb0dcd0615698a5cbe587c3f0fe57a54d8f5') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;" RUN php composer-setup.php RUN php -r "unlink('composer-setup.php');" RUN mv composer.phar /usr/local/bin/composer # 環境変数設定 ENV COMPOSER_ALLOW_SUPERUSER 1 ENV COMPOSER_HOME "/opt/composer" ENV PATH "$PATH:/opt/composer/vendor/bin" # Laravelインストール RUN composer global require "laravel/installer" # Laravelプロジェクト作成 WORKDIR /var/www RUN composer create-project laravel/laravel laravel FROM php:7.3-fpm-alpine # ビルド用コンテナから必要なコンテンツをコピー COPY --from=vender --chown=www-data:www-data /var/www/ /var/www/
操作
コマンドは全て最上位ディレクトリの docker
から行う想定です。
Nginxコンテナビルド
docker build nginx/. -t nginx --squash
Laravelコンテナビルド
docker build laravel/. -t laravel --squash
docker-composeで起動
docker-compose up
ブラウザで表示を確認
http://localhost:8000 にアクセスすることで以下のサンプルを表示します。
解説
Nginxコンテナ
ベースイメージ
FROM nginx:1.17-alpine
ベースイメージにはNginx公式リポジトリにあるnginx:1.17-alpine
を使用しました。
2019/7/14現在のNginxの最新が1.17であり、軽量化を目的にAlpineLinux版を使いたかったためです。
80番ポートの開放やNginxの起動についてはベースイメージ内で既に設定されているため、今回のDokcerfileには記述していません。
default.conf
COPY default.conf /etc/nginx/conf.d/default.conf
設定はローカルに用意したdefault.conf
をイメージにコピーして配置します。
FastCGI設定のほとんどは一般的な設定のため、特徴的なものだけ解説します。
root
root /var/www/laravel/public;
ドキュメントルートはLaravelコンテナのアプリケーションが配置されているディレクトリを指定します。
fastcgi_pass
fastcgi_pass laravel:9000;
UnixソケットかTCPを指定できますが、Unixソケットではコンテナを越えられないため、TCPで設定します。
アドレスの指定にはDockerのNamespaceを利用します。
Laravelコンテナ
前回のDockerfileからの差異のみ解説します。
ベースイメージ
FROM php:7.3-fpm-alpine
実行用イメージのベースを php:7.3-alpine
からphp:7.3-fpm-alpine
に変更しました。
これによってデフォルトでphp-fpmがインストールされた状態から設定を行えばよくなります。
9000番ポートの開放やphp-fpmの起動についてはベースイメージ内で既に設定されているため、今回のDokcerfileには記述していません。
Laravelコンテンツのオーナー変更
COPY --from=vender --chown=www-data:www-data /var/www/ /var/www/
php:7.3-fpm-alpine
のphp-fpm初期設定では、php-fpmのワーカ起動ユーザはwww-data
になっています。
COPYコマンドで配置したLaravelコンテンツはrootがオーナーになってしまうため、そのままだと権限エラーとなります。
そこで、--chown
オプションを使用し、オーナーをwww-data
へ変更しています。--chown
オプションはBashでいうところのchown -R
となるため、ディレクトリがあっても再帰的に処理してくれます。
docker-compose
今回からコンテナが2つになったため、操作簡略のためにdocker-compose
を導入しました。docker-compose
には起動時のオプション設定や、複数コンテナのビルド、依存関係制御など様々な機能がありますが、ここではコンテナ起動/停止とポートオプションのみ使用しています。
複数コンテナのビルドを使用しない理由
本当であれば使用したかったのが本音です。
しかしながら2019/7/14現在、BuildKitやsquashオプションに対応していないため、あえてdockerコマンドでビルドを行っています。
Tips
コンテナイメージ内にあるファイルをローカルにコピーする
設定ファイルを作成する際に、デフォルトの設定をローカルにコピーし、それを改変して作成していくことはよくあると思います。
コンテナではSCPが使えないため、代わりにdocker cp
コマンドを使用します。
今回のdefault.confの場合は、以下のようにしてコピーしました。
docker run -d --name nginx nginx:1.17-alpine docker cp $(docker ps --filter name=nginx -aq):/etc/nginx/conf.d/default.conf .
コンテナイメージの履歴を確認する
FROMで使用するベースイメージには予めポートの開放やデーモンの起動が設定されている場合があります。
今回でいうところのNginxやphp-fpmですね。
それを確認するにはdocker history
コマンドを使用します。
例としてphp-fpmのhistoryを確認してみます。
docker history --format {{.CreatedBy}} php:7.3-fpm-alpine /bin/sh -c #(nop) CMD ["php-fpm"] /bin/sh -c #(nop) EXPOSE 9000 /bin/sh -c #(nop) STOPSIGNAL SIGQUIT /bin/sh -c set -eux; cd /usr/local/etc; if… /bin/sh -c #(nop) WORKDIR /var/www/html /bin/sh -c #(nop) ENTRYPOINT ["docker-php-e… /bin/sh -c docker-php-ext-enable sodium ...
このようにズラズラとコマンドが表示されるかと思います。
これは実行日次のtimestampが新しい順で上から並んでいます。
これを見るとベースイメージの最後に、9000番ポートの開放とphp-fpmの実行が行われているため、今回のDockerfileではポートの開放とデーモンの起動が不要なことがわかります。
まとめ
Nginx+php-fpmに加えて、docker-composeも導入してみました。
そんなに特殊な設定を行ったわけではありませんが、Dockerfileの書き方やコンテナ特有の設定等はお伝えできたかと思います。