LoginSignup
16
10

More than 5 years have passed since last update.

Dockerでnginx + php-fpm(CakePHP) + MySQL を立ち上げるまでの長い道のり

Last updated at Posted at 2018-10-08

アウトライン

  1. 完成後の構築後イメージ
  2. 構築
    1. ディレクトリ構成
    2. nginx
    3. php-fpm + CakePHP
    4. MySQL
  3. 躓いたポイント

完成後の構築イメージ

白抜きの四角は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

docker-compose.yml
  nginx:
    build: ./nginx/
    ports:
      - 8080:80
    links:
      - phpfpm
    volumes:
      - ./data:/var/www/html
Dockerfile
FROM nginx:1.15.5-alpine
COPY ./default.conf /etc/nginx/conf.d/default.conf

■volumes
ホストOSの./dataディレクトリをドキュメントルートの上位ディレクトリ/var/www/htmlへマウントする。(実際のドキュメントルートディレクトリは後ほどphp側で作成)

default.conf
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

docker-compose.yml
  phpfpm:
    build: ./phpfpm/
    links:
      - mysql
    volumes:
      - ./data:/var/www/html
Dockerfile
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

docker-compose.yml
  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は不要か?

接続確認

ホストOSからlocalhost:8080にアクセス
スクリーンショット 2018-10-08 21.21.43.png

躓いたポイント

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のリソースを両方のコンテナからアクセスできるようにした。

16
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
10