業務やプライベート開発でCakePHP3を使用することが多いのですが、環境構築で未だに結構時間が取られがちです。これではいけません。webプログラマたるもの常に迅速で正確な環境構築ができるよう、地道に鍛錬を重ねましょう。ということで今回はCakePHP3の環境構築RTAに挑戦してみます。
前提
Vagrant / VirtualBox
Windows上にLinux仮想環境を構築するために使用します。ちなみにVagrantのバージョンは1.9.8、VirtualBoxのバージョンは5.1.30を使用しています。
Docker
Vagrant環境上に直接構築してもいいのですが、流行りの技術を取り入れます。PHPMyAdminやMailCatcherなどの、Dockerを使用することで簡単に立ち上げられる便利ツールをあわせて導入することでDockerのメリットをふんだんに活かしていきましょう。
docker-compose
Dockerのオーケストレーションツールとして使用します。最近はKubernetesなんかも流行ってるようですが、ここは使い慣れたもので行きます。
PHP
バージョンは7.2の想定です。コンテナはphp:7.2-apacheを使用するのでPHPとapacheを一挙に入れられてお得です。
MySQL
mysql:5.6を使用します。
nginx
本筋の環境構築とは外れるのですが、dockerで環境構築をした際にいちいちポート番号付きでアクセスするのは面倒なので、jwilder/nginx-proxyコンテナを噛ませることでドメイン付きのアクセスができるようにしておきます。
PHPMyAdmin
PHPer御用達のDBクライアントです。ローカル環境には入れておくと何かと便利な場面があります。docker-compose.ymlに記述しておくだけで使えるようになるので今回も入れておきます。
MailCatcher
これも便利なので、dockerで環境構築をするときは必ず入れています。ブラウザ上からメールの挙動を確認できると同時に、ローカル環境から本番メールアドレスに向けた誤送信を防ぎます。
下準備
dockerで環境構築を行うにあたり、dockerホストとなるLinux環境を作っておく必要があります。一度dockerホスト環境を作ってしまえばあとはその中に各ローカル環境を作って使い回せるので、この下準備を行うのは一度限りです。
Vagrantfileの作成
まずはどこか適当なところにVagrantfileを作成し、下記のように記述します。
# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure("2") do |config|
config.vm.box = "bento/centos-7.3"
config.vbguest.auto_update = false
config.vm.hostname = "local-docker"
config.vm.network "private_network", ip: "192.168.33.35"
config.ssh.insert_key = false
# ローカルに作成したdocker用ディレクトリのパスに書き換える
config.vm.synced_folder "C:\\Users\\xxxxx\\Documents\\docks", "/home/vagrant/docks/"
# Docker環境内で使用するドメイン名を入力する
config.hostsupdater.aliases = [
"local-example.com",
]
config.vm.provision "shell", :path => "docker-vagrant_init.sh", :privileged => false
end
boxはbento/centos-7.3を使用しています。coreos-vagrantも試してみたのですが、Windowsで動かしているせいかマウントがちょっと不安定でした。
vagrantのプラグインとして、vagrant-vbguestとvagrant-hostsupdaterが入っている前提です。あらかじめvagrant plugin installしておいてください。
プロビジョニングファイルの作成
すでに先程のVagrantfileで設定されていますが、vagrant環境の構築時のみ実行されるプロビジョニングファイルを作成し、初期の構築作業を自動化しておきます。
docker-vagrant_init.shというファイル名でVagrantfileと同じ場所に置いてください。
sudo tee /etc/yum.repos.d/docker.repo <<-'EOF' [dockerrepo] name=Docker Repository baseurl=https://yum.dockerproject.org/repo/main/centos/$releasever/ enabled=1 gpgcheck=1 gpgkey=https://yum.dockerproject.org/gpg EOF sudo yum -y install docker-engine sudo service docker start sudo chkconfig docker on docker -v curl -L https://github.com/docker/compose/releases/download/1.6.2/docker-compose-`uname -s`-`uname -m` > /tmp/docker-compose sudo mv /tmp/docker-compose /usr/bin/docker-compose sudo chmod 775 /usr/bin/docker-compose sudo docker-compose -v
dockerおよびdocker-composeのインストールをしています。
あとはvagrant upを実行すれば、dockerおよびdocker-composeの入ったdockerホスト環境が構築されるはずです。これを使ってCakePHP3環境を構築していきましょう。
必要なファイルの設置
それではdockerを使用してCakePHP3の環境を構築します。 まず、docker-compose.ymlはこんな感じ。
version: '2'
volumes:
db-data:
services:
db:
image: mysql:5.6
environment:
- MYSQL_ROOT_PASSWORD=root
- MYSQL_DATABASE=example
volumes:
- "db-data:/var/lib/mysql"
command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_general_ci
web:
build: ./web/
volumes:
- "./web/html:/var/www/html/"
links:
- db
environment:
VIRTUAL_HOST: local-example.com
CERT_NAME: docker
HTTPS_METHOD: noredirect
proxy:
image: jwilder/nginx-proxy
ports:
- 80:80
- 443:443
volumes:
- "./proxy/certs:/etc/nginx/certs"
- "/var/run/docker.sock:/tmp/docker.sock:ro"
restart: always
pma:
image: phpmyadmin/phpmyadmin:latest
environment:
- PMA_HOST=db
- PMA_USER=root
- PMA_PASSWORD=root
links:
- db
environment:
VIRTUAL_HOST: pma.local-example.com
CERT_NAME: docker
HTTPS_METHOD: noredirect
smtp:
image: schickling/mailcatcher
ports:
- "1025:1025"
environment:
VIRTUAL_HOST: mail.local-example.com
HTTPS_METHOD: noredirect
VIRTUAL_PORT: 1080
このdocker-compose.ymlだけでは起動しないので、各コンテナについて細かく設定を見ていきます。
dbコンテナ
mysql:5.6イメージをそのまま使用します。
Dockerfileや別途設定ファイルは必要ありません。
db-dataボリュームを作成し、/var/lib/mysql/をマウントさせることでデータの永続化をさせます。
なお、このようにして永続化したデータを削除したい場合はdocker-compose down時に-vオプションを付けましょう。
proxyコンテナ
各コンテナに対してドメインを紐づけるため、専用のnginxコンテナを建てます。 イメージはjwilder/nginx-proxyを使用しています。
下記記事を参考にさせていただきました。
詳しいことは参考記事を見ていただけるとよいのですが、docker-compose.ymlでドメインを紐づけたいコンテナについて、
environment:
VIRTUAL_HOST: local-example.com
CERT_NAME: docker
HTTPS_METHOD: noredirect
このように環境変数の設定をしておくと、nginx-proxyコンテナが各コンテナにドメインの紐付けを行ってくれます。
ちなみにCERT_NAMEは使用する証明書の名前が入ります。proxyコンテナの/etc/nginx/certs/内にdocker.crtおよびdocker.keyを設置しておきましょう。
smtpコンテナ
MailCatcher用のコンテナです。
こちらもschickling/mailcatcherイメージをそのまま使用します。
ここでは1080番ポートと1025番ポートを開いています。詳しく言えば1080番はブラウザでの表示用ポートのためVIRTUAL_POSTでnginx-proxyから繋ぐポート番号を指定し、1025番はSMTP用のポートで、主にwebコンテナで使用されることを想定しています。
webコンテナ
php:7.2-apacheイメージを使用します。 Dockerfileおよびapache設定ファイルを別途用意する必要があります。 CakePHP3環境の構築に必要なDockerfileはこんな感じです。
FROM php:7.2-apache RUN apt-get update RUN apt-get -y install git zlib1g-dev libicu-dev zip unzip RUN docker-php-ext-install pdo pdo_mysql mysqli mbstring intl zip RUN apt-get install -y ssmtp mailutils RUN curl -sS https://getcomposer.org/installer | php RUN mv composer.phar /usr/local/bin/composer RUN composer self-update RUN composer global require hirak/prestissimo COPY ./conf/ /etc/apache2/sites-enabled/ COPY ./conf/ssmtp.conf /etc/ssmtp/ssmtp.conf RUN a2enmod rewrite RUN rm -f /etc/apache2/sites-enabled/000-default.conf RUN rm -f /etc/apache2/sites-available/000-default.conf RUN service apache2 start
各環境に合わせて必要なものがあればここで入れておきましょう。
7行目でCOPYしているapacheの設定ファイルはこのように設定します。今回はexample.confというファイル名にしました。
<VirtualHost *:80>
ServerAdmin webmaster@localhost
DocumentRoot /var/www/html/example/webroot/
ServerName local-example.com
<Directory /var/www/html/example/>
Options FollowSymLinks
AllowOverride All
Require all granted
</Directory>
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
また、8行目のCOPYではsmtpの設定をしています。
ここで設定をしておかないと先程作成したsmtpコンテナがwebコンテナからのメール送信に利用されないので注意です。
mailhub=smtp:1025 FromLineOverride=YES
また、ここでwebコンテナにcomposerをインストールし、パスを通しておきます。composer global requireしているのはcomposerの動作を高速化するプラグインです。
pmaコンテナ
PHPMyAdmin用のコンテナです。
phpmyadmin/phpmyadminイメージをそのまま利用できます。environmentで各種設定をしておきましょう。

最終的にはこんなディレクトリ構成になります。
ここまでの自動化
あとは環境を起動するだけですが、ここまでの作業が多すぎて面倒なので自動化をはかることにしました。
Pythonで作ってます。勢いだけの作り捨てなので動作確認はあまりしっかりしていません。ローカルにダウンロードし、プロジェクト名を引数としてlampta.pyを実行するとlamptaディレクトリと同じところにプロジェクト名でディレクトリが切られ、環境構築に必要なファイル群が生成されます。
lampta.py example
証明書だけは勝手に生成されないので、proxy/certs/docker.crtおよびproxy/certs/docker.keyは自分で作成してください。
環境の起動
それではここまで作ってきた環境を実際に起動しましょう。
Dockerfileでのドメイン設定
docker-compose.ymlで紐付けたドメインについてVagrantfileにも記載しておくことで、Vagrantを起動した際にWindowsのhostsファイルへ設定がされるようにしておきます。
config.hostsupdater.aliases = [
"local-example.com",
"pma.local-example.com",
"mail.local-example.com",
]
コンテナ起動
SSHクライアントなどでdockerの入ったVagrant環境にログインし、docker-compose.ymlのあるところでdocker-composeを起動します。
docker-compose up
初回起動時は作成されていないイメージの構築も同時に行われるので少し時間がかかります。起動したらこのプロセスは各コンテナのログ表示用にとっておき、別の接続でコンテナ内に入って作業を行いましょう。
webコンテナ内での作業
このあとはwebコンテナ内でCakePHP3のインストール作業を行いましょう。まずはwebコンテナに入ります。
docker exec -it example_web_1 /bin/bash
CakePHP3公式ドキュメントにしたがって下記コマンドを実行すればCakePHP3環境が完成です。ブラウザからdocker-compose.ymlで設定したドメインにアクセスしてみましょう。
composer create-project --prefer-dist cakephp/app example
おわりに
RTAは6分8秒でした。やったね。