tsyama記

プログラミングとそのほか

CakePHP3環境構築RTA

業務やプライベート開発で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を使用するのでPHPapacheを一挙に入れられてお得です。

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-vbguestvagrant-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を使用しています。

下記記事を参考にさせていただきました。

nginx-proxy(Docker)で設定なしリバースプロキシ - Fusicきばんブログ

詳しいことは参考記事を見ていただけるとよいのですが、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の動作を高速化するプラグインです。

参考:composerを速くするプラグイン・prestissimoを作った: Architect Note

pmaコンテナ

PHPMyAdmin用のコンテナです。 phpmyadmin/phpmyadminイメージをそのまま利用できます。environmentで各種設定をしておきましょう。

f:id:tsyama-desu:20180901130038p:plain

最終的にはこんなディレクトリ構成になります。

ここまでの自動化

あとは環境を起動するだけですが、ここまでの作業が多すぎて面倒なので自動化をはかることにしました。

tsyama/lampta

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秒でした。やったね。