CentOS 7 + Apache + php-fpm + mariaDB でdocker-compose環境を作る
はじめに
業務で使用しているのがCentOSなので公式のphpイメージがあるかと探して見たんですが、
公式のイメージはDebianなのでdocker-composeでCentOSのLAMP環境を作成しました。
せっかくなのでネットでよくみるApacheのコンテナ内に直接PHPをインストールする形ではなく
php-fpm用の別コンテナを立てて各コンテナを連携します。
完成品はこちら
手順はいいから現物はよっ!という方はこちらのリポジトリにあります。
temori1919/docker-lamp
構成
ディレクトリ構造
docker-lamp/
├── web
│ ├── logs
│ ├── Dockerfile
│ └── docker.conf #[/etc/httpd/conf.d]にコピーするconfファイル
├── php
│ ├── xdebug.ini #[/usr/local/etc/php/conf.d]にコピーするphp.iniファイル
│ └── Dockerfile
├── db
│ ├── logs
│ ├── my.cnf #[/etc/mysql/conf.d]にコピーするmysql confファイル
│ └── Dockerfile
├── code codeの下がドキュメントルート([/var/www/html]にマウントされる)
│ ├── example
| ├── gulpfile.js
│ └── config
| └── default.json.example
└── docker-compose.yml
docker-compose.yml
version: '3.7'
services:
# centos7 apache2.4.*(http2)
web:
build: ./web
ports:
- '80:80'
- '443:443'
depends_on:
- php
volumes:
- ./code:/var/www/html
- ./web/logs:/var/log/httpd
- cert:/etc/ssl/private
restart: always
env_file: .env
# php-fpm
php:
build: ./php
depends_on:
- db
ports:
- '9000'
volumes:
- ./code:/var/www/html
restart: always
env_file: .env
# mariaDB
db:
build: ./db
restart: always
env_file: .env
ports:
- 3306:3306
volumes:
- ./db/logs:/var/log/mysql
- datastore:/var/lib/mysql
# phpMyadmin
phpmyadmin:
depends_on:
- db
image: phpmyadmin/phpmyadmin
env_file: .env
ports:
- 8080:80
# php Composer
composer:
image: composer
# node js (include gulp)
node:
build: ./node
restart: always
tty: true
ports:
- '8081'
depends_on:
- web
volumes:
- ./code:/var/www/html
volumes:
cert:
datastore:
1.CentOS + Apacheコンテナ
Dockerfile
FROM centos:7
RUN yum update -y
RUN yum -y remove httpd httpd.x86_64 httpd-tools.x86_64
# install leatest apache2.4.*
RUN yum install -y epel-release && \
yum -y install https://centos7.iuscommunity.org/ius-release.rpm && \
sed -i -e "s/enabled *= *1/enabled=0/g" /etc/yum.repos.d/ius.repo && \
sed -i -e "s/enabled *= *1/enabled=0/g" /etc/yum.repos.d/epel.repo
RUN yum --enablerepo=epel -y install nghttp2 && \
yum -y install epel-release && \
yum -y install mailcap system-logos && \
yum -y install openssl && \
yum -y --disablerepo=base,extras,updates --enablerepo=ius install httpd mod_ssl && \
yum clean all
RUN sed -i -e "s|LoadModule mpm_prefork_module modules/mod_mpm_prefork.so|#LoadModule mpm_prefork_module modules/mod_mpm_prefork.so|" /etc/httpd/conf.modules.d/00-mpm.conf && \
sed -i -e "s|#LoadModule mpm_event_module modules/mod_mpm_event.so|LoadModule mpm_event_module modules/mod_mpm_event.so|" /etc/httpd/conf.modules.d/00-mpm.conf
# make SSL server certificate
RUN mkdir -p /etc/ssl/private && \
openssl req -new -newkey rsa:2048 -nodes -out /etc/ssl/private/server.csr -keyout /etc/ssl/private/server.key -subj "/C=/ST=/L=/O=/OU=/CN=*.lvh.me" && \
openssl x509 -days 3650 -req -signkey /etc/ssl/private/server.key -in /etc/ssl/private/server.csr -out /etc/ssl/private/server.crt
COPY docker.conf /etc/httpd/conf.d/docker.conf
# dockre can not use systemd without permission, apahce is started with httpd
CMD ["/usr/sbin/httpd", "-DFOREGROUND"]
今回の要件ではPHPを別コンテナ立てする予定なので、Apacheのconfファイルで.phpのファイルだけをphp-fpmのコンテナで動かしたかった。
当初は「ProxyPassMatch」を使ってphp拡張子のファイルをphp-fpmコンテナで動かそうと思っていましたが、以下のような問題点があるようです。
(ファイルシステムと関係がないプロクシーなので) DirectoryIndex が効かない
(同じ理由で) .htaccess によるディレクトリごとの制御ができない
PATH_INFO がおかしい。そのため PHP の PHP_SELF サーバー変数もおかしい
PHP :: Bug #65641 :: PHP-FPM incorrectly defines the SCRIPT_NAME variable when using Apache
Apache2.4.10以上のインストール
そこでApache2.4.10以上で書けるようになったFilesMatchディレクティブを使用します。
CentOS7のyumでApacheをインストールすると2.4.6が入ってしまうので、
Apacheのリポジトリを追加します。
# この辺りの記述
yum -y install https://centos7.iuscommunity.org/ius-release.rpm && \
sed -i -e "s/enabled *= *1/enabled=0/g" /etc/yum.repos.d/ius.repo && \
sed -i -e "s/enabled *= *1/enabled=0/g" /etc/yum.repos.d/epel.repo
RUN yum --enablerepo=epel -y install nghttp2 && \
yum -y install epel-release && \
yum -y install mailcap system-logos && \
yum -y install openssl && \
yum -y --disablerepo=base,extras,updates --enablerepo=ius install httpd mod_ssl && \
yum clean all
ついでにオレオレ証明も使いたいので、opensslやmod_sslモジュールも入れておきます。
2.php-fpmコンテナ
Dockerfile
FROM php:7.2-fpm
RUN mv $PHP_INI_DIR/php.ini-development $PHP_INI_DIR/php.ini && \
sed -i -e "s|;session.save_path = "/tmp"|session.save_path = "/tmp" |" /usr/local/etc/php/php.ini && \
docker-php-ext-install pdo_mysql && \
pecl install mailparse-3.0.2 && \
pecl install xdebug-2.6.1 && \
docker-php-ext-enable mailparse xdebug
COPY ./xdebug.ini $PHP_INI_DIR/conf.d/
php-fpmのインストールを行います。
ついでにメールパーサーのmailparseとxdebugもインストールしておきます。
3.confファイル
docker.conf
UseCanonicalName Off
EnableSendfile off
<VirtualHost *:80>
ServerName lvh.me
ServerAlias *.lvh.me
VirtualDocumentRoot /var/www/html/%1/public
<FilesMatch \.php$>
SetHandler "proxy:fcgi://php:9000"
</FilesMatch>
<Directory /var/www/html>
DirectoryIndex index.php
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
DirectoryIndex index.php index.html
</VirtualHost>
<VirtualHost *:443>
SSLEngine on
SSLCertificateFile /etc/ssl/private/server.crt
SSLCertificateKeyFile /etc/ssl/private/server.key
ServerName lvh.me
ServerAlias *.lvh.me
VirtualDocumentRoot /var/www/html/%1/public
<FilesMatch \.php$>
SetHandler "proxy:fcgi://php:9000"
</FilesMatch>
<Directory /var/www/html>
DirectoryIndex index.php
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
DirectoryIndex index.php index.html
</VirtualHost>
FilesMatchでphpコンテナとデフォルトのポート9000を指定してあげます。
また、以下のディレクトリがドキュメントルートになるのですが、
ドキュメントルートの下に複数プロジェクトを置いて開発できるようにしたかったのでVirtualDocumentRootを利用して、プロジェクトのディレクトリ名がドメインになるように設定しています。
docker-lamp/code
lvh.meというドメインを127.0.0.1にDNS登録してくれている人がいるらしいので利用させてもらいました。
[ディレクトリ名].lvh.me
でアクセス可能になります。
4.その他コンテナ
mariaDBやcomposer、phpmyadmin、テストのタスクランナー用のgulpを動かすためのnodeコンテナを入れています。
詳細はリポジトリのREADME.mdを見てください。
temori1919/docker-lamp
5.最後に
イメージが豊富にあってすぐに環境作成ができるdockerは本当に素晴らしいですね。
今はまだローカル開発やツールぐらいでしか使用していませんが、今後はproductionレベルでの使用もしていけるように勉強していければと思います。
それでは皆さまも素敵なdockerライフをお過ごし下さい。
Discussion