背景
Apache + php-fpm の環境を別々の Docker コンテナで構築しようと思ったのですが、
同一コンテナで構築している方々が多かったため、記事にしてみました。
別々のコンテナで構築するメリットは、Apache、php-fpm どちらかのバージョンアップをする際に片方のコンテナのみの停止、DockerFile編集、起動で良いことです。
最低限の設定しかしませんので、Webサーバにこの手順を使用する際にはセキュリティやログの出力先等、詳細な設定をしてください。
以前、記事にした環境構築を参考にしております。
環境
ホストOS:Amazon Linux release 2 (Karoo)
コンテナOS:CentOS Linux release 7.9.2009 (Core)
Docker version 20.10.4
docker-compose version 1.29.2
Apache/2.4.6
PHP 5.4.16 (fpm-fcgi)
手順
ディレクトリ・ファイル配置
ディレクトリとファイルの配置場所の構成は以下のようにしました。
ApachePHPFPM
|
|- Apache
| |- Dockerfile
| |- httpd-original.conf
|
|- PHPFPM
| |- Dockerfile
| |- www-original.conf
|
|- docker-compose.yml
Apache コンテナ
DockerFile
DockerFile は以下のように記述しております。
# ベースイメージの指定
FROM centos:centos7
# yum update
RUN yum update -y
# Apache のインストール
RUN yum install -y httpd
# Apache の設定ファイルを配置
COPY httpd-original.conf /etc/httpd/conf/httpd.conf
# Apache の起動
ENTRYPOINT ["/usr/sbin/httpd", "-DFOREGROUND"]
Apache の設定ファイル
Apache の設定ファイルは httpd-original.conf
というファイル名にしてます。
ドキュメントルートの設定に、php-fpm に処理を渡す記述を書いただけです。
以下のように記述しています。
ServerRoot "/etc/httpd"
Listen 80
Include conf.modules.d/*.conf
User apache
Group apache
ServerName localhost:80
ServerAdmin root@localhost
<Directory />
AllowOverride none
Require all denied
</Directory>
DocumentRoot "/var/www/html"
<Directory "/var/www">
AllowOverride None
Require all granted
</Directory>
<Directory "/var/www/html">
<FilesMatch \.(html|php)$>
SetHandler "proxy:unix:/var/run/php-fpm/php-fpm.sock|fcgi://php-fpm"
</FilesMatch>
Options Indexes FollowSymLinks
AllowOverride None
Require all granted
</Directory>
<IfModule dir_module>
DirectoryIndex index.html index.php
</IfModule>
<Files ".ht*">
Require all denied
</Files>
ErrorLog "logs/error_log"
LogLevel warn
<IfModule log_config_module>
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%h %l %u %t \"%r\" %>s %b" common
<IfModule logio_module>
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio
</IfModule>
CustomLog "logs/access_log" combined
</IfModule>
<IfModule alias_module>
ScriptAlias /cgi-bin/ "/var/www/cgi-bin/"
</IfModule>
<Directory "/var/www/cgi-bin">
AllowOverride None
Options None
Require all granted
</Directory>
<IfModule mime_module>
TypesConfig /etc/mime.types
AddType application/x-compress .Z
AddType application/x-gzip .gz .tgz
AddType text/html .shtml
AddOutputFilter INCLUDES .shtml
</IfModule>
AddDefaultCharset UTF-8
<IfModule mime_magic_module>
MIMEMagicFile conf/magic
</IfModule>
EnableSendfile on
IncludeOptional conf.d/*.conf
PHPFPM コンテナ
DockerFile
# ベースイメージの指定
FROM centos:centos7
# yum update
RUN yum update -y
# php-fpm のインストール
RUN yum install -y php-fpm
# php-fpm の設定ファイルを配置
COPY www-original.conf /etc/php-fpm.d/www.conf
# Apache の起動
ENTRYPOINT ["php-fpm"]
PHPFPM の設定ファイル
PHPFPM の設定ファイルは www-original.conf
というファイル名にしてます。
listen
にソケットファイルの場所を記述しています。
他は以下のように記述しています。
[www]
listen = /var/run/php-fpm/php-fpm.sock
listen.owner = apache
listen.group = apache
listen.mode = 0660
user = nobody
group = nobody
pm = static
pm.max_children = 2
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
docker-compose ファイル
Apache と PHPFPM はUNIXドメインソケットで通信しています。
なので、socket
というボリュームを作成し、このボリュームを Apache , PHPFPM コンテナのソケットファイルを配置するディレクトリでマウントしております。
また、ホストの /opt/app
に Apache コンテナのドキュメントルートをマウントして、ホスト側で公開するファイルを配置できるようにしてます。
PHPFPM コンテナ側でも/opt/app
にドキュメントルートをマウントして、処理するファイルが見えるようにします。
version: "3.9"
services:
apache:
build:
context: ./Apache
dockerfile: Dockerfile
ports:
- "80:80"
volumes:
- "socket:/var/run/php-fpm/"
- "/opt/app:/var/www/html"
php-fpm:
build:
context: ./PHPFPM
dockerfile: Dockerfile
volumes:
- "socket:/var/run/php-fpm/"
volumes:
socket:
公開するファイルの配置
今回は phpinfo を表示して動作確認します。
/opt/app
配下にファイルを配置します。
<?php echo phpinfo(); ?>
docker-compose によるコンテナ作成
ApachePHPFPM
ディレクトリ内で以下コマンドを実行するだけです。
sudo docker-compose up -d --build
動作確認
URLにアクセスして phpinfo が表示されるか確認します。
表示されればOKです。
はまったところ
最初はソケット通信だとソケットファイルを使って、Apache コンテナからPHPFPM コンテナに index.php
の内容を送ってくれるものだと思っており、PHPFPM 側から index.php のファイルが見えないように設定しておりました。
それだとFile not found.
になってしまうのでご注意ください。
最後に
一度、DockerFile
や docker-compose.yml
を書いてしまえば、1つのコマンドで同じ環境を複数作れるのはとても魅力的に感じました。
作業効率を良くするために docker の勉強は続けていきたいと思います。
最後まで読んでいただきありがとうございました。