フリーランスのためのネットビジネス専門学校 ネットで独立開業を目指す人を応援
フリーランスのためのネットビジネス専門学校 ネットで独立開業を目指す人を応援

PHPでリフレクションはこうでしょうが!

アウトライン

  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プロジェクトの初期化をDockerfileのRUNコマンド内で実行

docker-composeでドキュメントルートをマウントすると、
1. コンテナ起動時に
2. ホストOSのディレクトリ構成をコンテナにマウント(上書き)する。

Dockerfileで作られたCakePHPのプロジェクトはマウント時に上書きされて無くなる。
対応策として、CakePHPのプロジェクトはコンテナ起動後に手動で作成した。
DockerfileのCMDを使えば、手動が不要になる気がする。

静的コンテンツが返却されない

nginxコンテナとphpコンテナでホストOSをマウントしていなかった。そのため、CakePHPのTOPページをアクセスしてもcssやpngのようなファイルが返却されなかった。理由は簡単で、nginx側コンテナにはcss, pngなどの静的ファイルが存在しないから。
言われてみれば当たり前だけど困った。
nginxコンテナからphpコンテナをマウントする方法も検討したけど、どのパスがどのパスとマウントされるかよく分からなかった。
対応策としてホストOSのディレクトリをマウントしてCakePHPのリソースを両方のコンテナからアクセスできるようにした。

[紹介元] PHPタグが付けられた新着投稿 – Qiita PHPでリフレクションはこうでしょうが!

コメント

記事に戻る

コメントを残す