どうも、若松です。
前回はLaravelをDockerで起動し、イメージを軽量化するところまで行いました。
https://qiita.com/t_wkm2/items/245288e42083ac7e4057
今回は、 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の書き方やコンテナ特有の設定等はお伝えできたかと思います。