はじめに
前の記事では、Docker に CentOS 8 と nginx をインストールする方法をご紹介しました。
この記事では、さらに PHP(php-fpm) のコンテナを構築して、Web(nginx) + App(PHP) という構成の環境を構築します。
フォルダ構成
Docker の設定ファイルなどのフォルダ構成は、以下の通りです。今回は、最初から Dockerfile と docker-compose.yml を使用します。
root ├── docker-compose.yml ├── php │ ├── Dockerfile │ └── www.conf ├── share │ └── src │ └── index.php └── web ├── Dockerfile └── nginx.conf
nginx の設定
nginx では、以下の Dockerfile を使用します。
Dockerfile
FROM centos:8 RUN dnf -y update RUN dnf install -y nginx COPY nginx.conf /etc/nginx/nginx.conf ENTRYPOINT /usr/sbin/nginx -g 'daemon off;' -c /etc/nginx/nginx.conf
nginx のインストールは、dnf を使用していますが yum と文法は変わらないので違和感はないです。
COPY
コマンドでは、ローカル(ホスト側)にあるnginx.conf
をコンテナにコピーしています。
ENTRYPOINT
コマンドでは、コンテナが終了してしまわないよう nginx をフォアグラウンドで実行しています。Docker では、バックグラウンドプロセスしか実行していないと、Docker がコンテナを終了してしまうのでこのような記述になっています。
なお、nginx をフォアグラウンドで実行する方法として、以下の記述がネットで多かったですがうまく動作しませんでした。
CMD ["/usr/sbin/nginx", "-g", "daemon off;"]
nginx の設定は以下のようになります。デフォルトと異なるのは、php-fpm の設定を追加していることです。
nginx.conf
# For more information on configuration, see: # * Official English Documentation: http://nginx.org/en/docs/ # * Official Russian Documentation: http://nginx.org/ru/docs/ user nginx; worker_processes auto; error_log /var/log/nginx/error.log; pid /run/nginx.pid; # Load dynamic modules. See /usr/share/doc/nginx/README.dynamic. include /usr/share/nginx/modules/*.conf; events { worker_connections 1024; } http { log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; types_hash_max_size 2048; include /etc/nginx/mime.types; default_type application/octet-stream; # Load modular configuration files from the /etc/nginx/conf.d directory. # See http://nginx.org/en/docs/ngx_core_module.html#include # for more information. include /etc/nginx/conf.d/*.conf; server { listen 80 default_server; listen [::]:80 default_server; server_name _; root /usr/share/nginx/html; # Load configuration files for the default server block. include /etc/nginx/default.d/*.conf; location / { try_files $uri $uri/ /index.php$is_args$args; } error_page 404 /404.html; location = /40x.html { } error_page 500 502 503 504 /50x.html; location = /50x.html { } location ~ \.php$ { fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_pass php:9000; fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param PATH_INFO $fastcgi_path_info; } } }
php-fpm の設定の以下のphp
は、Docker の設定によるコンテナ名を指しています。
fastcgi_pass php:9000;
PHP(php-fpm) の設定
Docker では、1コンテナ1プロセスという制約があるようなので、PHP(php-fpm) 用にコンテナを構築します。
Dockerfile は以下のようになります。
Dockerfile
FROM centos:8 RUN dnf -y update RUN dnf install -y php php-fpm RUN mkdir -p /run/php-fpm COPY www.conf /etc/php-fpm.d/www.conf RUN chown nginx:nginx /var/lib/php/session
/run/php-fpm
ディレクトリを作成しているのは、php-fpm 実行時にこのディレクトリがないとエラーになってしまうためです。また、COPY
コマンドでローカルからコンテナに php-fpm の設定ファイルをコピーしています。
php-fpm の設定ファイルは以下のようになります。デフォルトと異なるのは、user と group を nginx にしていることと、listen をプロセスファイルではなくポート番号にしていること、listen.acl_users をコメントアウトしていることです。
www.conf
[www] user = nginx group = nginx listen = 9000 ;listen.acl_users = apache,nginx listen.allowed_clients = 127.0.0.1 pm = dynamic pm.max_children = 50 pm.start_servers = 5 pm.min_spare_servers = 5 pm.max_spare_servers = 35 slowlog = /var/log/php-fpm/www-slow.log php_admin_value[error_log] = /var/log/php-fpm/www-error.log php_admin_flag[log_errors] = on php_value[session.save_handler] = files php_value[session.save_path] = /var/lib/php/session php_value[soap.wsdl_cache_dir] = /var/lib/php/wsdlcache
Docker Compose の設定
Docker Compose の設定で(docker-compose.yml
)、コンテナの設定を行います。
docker-compose.yml
version: '3' services: web: build: context: ./web/. ports: - "8080:80" links: - php volumes: - ./share/src:/usr/share/nginx/html php: build: context: ./php/. command: php-fpm -F volumes: - ./share/src:/usr/share/nginx/html
services
にweb
とphp
がありますが、それぞれ1つのコンテナになります。
build
は相対パスにある Dockerfile を使用してコンテナイメージのビルドを行います。
links
はコンテナ間の依存関係を記述します。web
のlinks
-php
と設定されることで、php
のコンテナをweb
のコンテナから参照できるようになります。
volumes
は、ホスト側とコンテナで共有するディレクトリを設定します。./share/src
には PHP のファイルを保存するので、web
とphp
で共通の設定になっています。
php
の command: php-fpm -F
は、php-fpm をフォアグラウンドで実行するためのコマンドです。いろいろ調べたのですが、Dockefile に記述する方法はダメで、docker-compose.yml
に記述する必要があるようです。
また下記コマンドを実行して、index.php を作成しておきます。
$ cd share/src $ echo "<?php phpinfo(); ?>" > index.php
コンテナの起動
下記コマンドを実行して、web と php の2つのコンテナをまとめて起動します。
$ docker-compose up -d
起動ができているか確認します。
$ docker-compose ps Name Command State Ports -------------------------------------------------------------------------------- wordpress_php_1 php-fpm -F Up wordpress_web_1 /bin/sh -c /usr/sbin/nginx Up 0.0.0.0:8080->80/tcp
問題なく起動していますね。
State に Exit
と表示されている場合はコンテナが起動していないので、原因を調べて対応する必要があります。
では、ブラウザでhttp://localhost:8080/index.php
を開いて、phpinfo() が出力されているか確認します。
問題なく表示されていますね。
これで、web と php のコンテナの通信が行われていて、php-fpm も問題なく動作していることが分かります。
コンテナの終了
作業が終了したら、下記コマンドでコンテナを終了して削除します。
$ docker-compose down Stopping wordpress_web_1 ... done Stopping wordpress_php_1 ... done Removing wordpress_web_1 ... done Removing wordpress_php_1 ... done Removing network wordpress_default
おわりに
Docker で CentOS に nginx をインストールして PHP(php-fpm) と連携するというのはマイナーなようで、ネットで調べてもあまり情報がありませんでした。トラブルシューティングの情報はほぼない状態でしたね。リリースされてから1ヶ月経っていない CentOS 8 なのでさらに情報がなかったです。
みなさん、nginx の公式のコンテナイメージを使用されているのでしょうね。だけど、OS が固定されることもあると思うのですが、その場合はどうしているのでしょう?苦労してはいるけれど、情報が共有されてないだけ?
この記事がお役にたてば幸いです。