Edited at

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 empm_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ライフをお過ごし下さい。