アウトライン
- 完成後の構築後イメージ
- 構築
- ディレクトリ構成
- nginx
- php-fpm + CakePHP
- MySQL
- 躓いたポイント
完成後の構築イメージ
白抜きの四角はdockerコンテナ。nginx, php-fpm, MySQLのコンテナを利用する。
青色の四角はホストOSのディレクトリ。
ポイント
nginxとphp-fpmがホストOSの同一ディレクトリをマウントする。
構築
ディレクトリ構成
ホストOS側からみた設定ファイル等のディレクトリ構成
.
├── data
├── docker-compose.yml
├── nginx
│ ├── Dockerfile
│ └── default.conf
└── phpfpm
└── Dockerfile
■dataディレクトリ
nginxとphpが共通のドキュメントルートを利用するために利用。__静的ファイルをnginxが返却できるように同一のデータを閲覧できるようにする。__nginxが静的ファイルを返却する必要がないなら、全てのリクエストをphp-fpm側に流してしまえば良いため、同じ場所をマウントする必要はない。
nginx
nginx:
build: ./nginx/
ports:
- 8080:80
links:
- phpfpm
volumes:
- ./data:/var/www/html
FROM nginx:1.15.5-alpine
COPY ./default.conf /etc/nginx/conf.d/default.conf
■volumes
ホストOSの./dataディレクトリをドキュメントルートの上位ディレクトリ/var/www/htmlへマウントする。(実際のドキュメントルートディレクトリは後ほどphp側で作成)
server {
listen 80;
server_name _;
root /var/www/html/myapp/webroot;
index index.php
access_log /var/log/nginx/access_log;
error_log /var/log/nginx/error_log debug;
location / {
try_files $uri $uri/ /index.php$is_args$args;
}
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(\.+)$;
fastcgi_pass phpfpm:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
}
後の手順でmyapp
プロジェクトをCakePHPで作成する。CakePHPでは、myapp/webroot
をルートにするよう指示している。
try_files
では、左から順にそのリソースがあるか確認する。ない場合はCakePHPのindex.phpにリクエストする。静的コンテンツがあれば、nginxが静的コンテンツを返却する。
ポイントはfastcgi_passでphpfpm:9000
を指定すること。linksのおかげでphpfpmをnginxコンテナ内で名前解決できる。(Hostsファイルとかに書いてくれてるのかな?)
php-fpm + CakePHP
phpfpm:
build: ./phpfpm/
links:
- mysql
volumes:
- ./data:/var/www/html
FROM php:7.2.10-fpm-stretch
RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" && \
php -r "if (hash_file('SHA384', 'composer-setup.php') === '93b54496392c062774670ac18b134c3b3a95e5a5e5c8f1a9f115f203b75bf9a129d5daa8ba6a13e2cc8a1da0806388a8') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;" && \
php composer-setup.php && \
php -r "unlink('composer-setup.php');" && \
mv composer.phar /usr/local/bin/composer && \
apt-get update && \
apt-get install -y libicu-dev && \
docker-php-ext-install intl pdo_mysql mbstring && \
apt-get install -y git && \
apt-get install -y zip unzip && \
composer config -g repos.packagist composer https://packagist.jp && \
composer global require hirak/prestissimo
DockerfileではcomposerのセットアップとCakePHP用のライブラリ(intl, pdo_mysql)をインストールしている。composerが内部でgitやzip, unzipを利用しているようなのでインストールしておく。
Dockerfileの後半2行はcomposer高速化対応なので、削除しても問題ない。
コンテナ起動後、/var/www/html/にCakePHPプロジェクトを作成する。
composer create-project --prefer-dist cakephp/app myapp
MySQL
mysql:
image: mysql:8.0.12
environment:
MYSQL_DATABASE: my_app
MYSQL_USER: my_app
MYSQL_PASSWORD: secret
MYSQL_ROOT_PASSWORD: password
CakePHPのデフォルトのDB設定名に合わせて設定値を追加。MYSQL_ROOT_PASSWARD
は不要か?
接続確認
躓いたポイント
CakePHPプロジェクトのプロジェクトがコンテナ起動時に消去される
docker-composeでドキュメントルートをマウントすると、
1. コンテナ起動時に
2. ホストOSのディレクトリ構成をコンテナにマウント(上書き)する。
Dockerfileで作られたCakePHPのプロジェクトはマウント時に上書きされて無くなる。
対応策として、CakePHPのプロジェクトはコンテナ起動後に手動で作成した。
DockerfileのCMDを使えば、手動が不要になる気がする。
静的コンテンツが返却されない
nginxコンテナとphpコンテナでホストOSをマウントしていなかった。そのため、CakePHPのTOPページをアクセスしてもcssやpngのようなファイルが返却されなかった。理由は簡単で、nginx側コンテナにはcss, pngなどの静的ファイルが存在しないから。
言われてみれば当たり前だけど困った。
nginxコンテナからphpコンテナをマウントする方法も検討したけど、どのパスがどのパスとマウントされるかよく分からなかった。
対応策としてホストOSのディレクトリをマウントしてCakePHPのリソースを両方のコンテナからアクセスできるようにした。