今までMacのネイティブ環境でWordPress開発をしてきたけれど、
- クライアント環境に合わせてサーバー環境が切り替えられなかったので、開発内容によってクライアントサーバー上で動作しないこということが多発
- クライアントによっては入稿されたHTMLファイルがルート相対パスで書いてあったりして、そんなときにvhostsいじるのが嫌
- OSバージョンアップで環境が壊れたりする(実際にMarvericsからYosemiteにアップしたらhttpdが起動しなくなって大変だった)
- 追加のモジュールとかでどんどん環境が肥大していく
と諸々が面倒なので、Yosemiteをクリーンインストールしたタイミングで、流行のDockerを使った開発環境構築を試してみたメモ。
前提条件
- Mac OSX Yosemite 10.10.3
- Vagrant 1.7.2
- VirtualBox 4.3.26
やりたいこと
ローカルのドメイン毎に環境の違う複数の開発環境を作りたい。
- wordpress.local
汎用的なWordPress案件開発用 - static.local
静的サイト案件開発用
構築方法
Webサーバーコンテナ毎にVagrantfileを作成してプロキシVMを立ち上げ、その内部に関連するコンテナだけを立ち上げる。
- プロキシVM(wordpress.local)
- Webサーバーコンテナ
- MySQLコンテナ
- データコンテナ
- プロキシVM(static.local)
- Webサーバーコンテナ
ホストマシンからのアクセス
プロキシVMのIPアドレス(プライベートネットワーク)をVagrantfileから設定し、vagrant-hostsupdater を使ってローカルドメインを設定。
- プロキシVM(wordpress.local)
192.168.33.20 - プロキシVM(static.local)
192.168.33.30
この方法のメリット
- Vagrantfileのみで全ての設定が簡潔できるため、
docker run
でコンテナを1つ1つ立ち上げるよりも楽。 - VMに対してプライベートネットワークでIPアドレスを別々に割り振れるので、ホストマシンからのポートフォワードなどを考える必要がない。(プロキシVMとコンテナのポートフォワードは必要)
- Vagrantのプラグインでホスト名の設定なども自動で行えるので
vagrant up
のみで簡単に仮想環境が立ち上げられる。
構築環境
開発環境1(wordpress.local)
ディレクトリ構成
- srv/
- wordpress.local
- htdocs/
- {案件毎ディレクトリ}
- Vagrantfile
- proxy.Vagrantfile
- Dockerfile
- htdocs/
- wordpress.local
Vagrantfile
- MySQLコンテナはDocker公式のMySQLイメージを利用。
- Dataコンテナは軽さを追求してbusyboxイメージを利用。
- WebサーバーコンテナはDockerfileから生成。
- WebサーバーコンテナはSynced Folderでホストマシンの
htdocs/
を/var/www/html
としてNFSマウント。
参考:Vagrantで複数環境のSynced FolderにNFSを利用する方法 - Dockerfileのビルドディレクトリに
htdocs/
を含んでしまうとビルドにとんでもなく時間がかかるため、ビルドディレクトリの同期にはrsync
を使いhtdocs/
を除外するように。
Vagrant.configure(2) do |config|
# dockerプロバイダの初期設定
config.vm.provider "docker" do |docker|
docker.vagrant_machine = "wordpress_proxy"
docker.vagrant_vagrantfile = "proxy.Vagrantfile"
docker.host_vm_build_dir_options = {
:type => "rsync",
:rsync__exclude => ["htdocs"]
}
end
# データコンテナの立ち上げ
config.vm.define "wordpress_data" do |node|
node.vm.provider "docker" do |docker|
docker.name = "data"
docker.image = "busybox"
docker.remains_running = false
docker.volumes = %w(/var/lib/mysql)
end
end
# mysqlコンテナの立ち上げ
config.vm.define "wordpress_mysql" do |node|
node.vm.provider "docker" do |docker|
docker.name = "mysql"
docker.image = "mysql:5.5"
docker.create_args = %w(--volumes-from="data")
docker.ports = ["3306:3306"]
docker.env = {
MYSQL_ROOT_PASSWORD: "root"
}
end
end
# Webサーバーコンテナの立ち上げ
config.vm.define "wordpress_web" do |node|
node.vm.synced_folder "htdocs", "/var/www/html", type: "nfs", nfs_export: false, mount_options: ["nolock", "vers=3", "udp"]
node.vm.provider "docker" do |docker|
docker.name = "web"
docker.build_dir = "."
docker.create_args = %w(--volumes-from="data")
docker.ports = ["80:80"]
docker.link "mysql:mysql"
end
end
end
Webサーバーコンテナ用のDockerfile
- クライアントのサーバーにCentOSが多いため、公式のCentOSイメージを利用。
- Apacheと、PHP5.4(とりあえず必要なモジュールをいくつか)をインストール。
- Apacheの設定ファイル
welcome.conf
は開発に邪魔なので削除。 -
httpd.conf
の公開ディレクトリにAllowOverride All
を設定。 -
php.ini
を開発用にカスタマイズ。
FROM centos:6.6
MAINTAINER m.ietomi <jyokyoku@gmail.com>
# TimeZone設定
RUN echo 'ZONE"=Asia/Tokyo"' > /etc/sysconfig/clock
# httpdをインストール
RUN yum -y update && \
yum install -y httpd && \
rm -rf /etc/httpd/conf.d/welcome.conf
# httpd.confを編集
RUN sed -i -e '/<Directory "\/var\/www\/html">/,/<\/Directory>/s/ AllowOverride None/ AllowOverride All/' /etc/httpd/conf/httpd.conf
# phpをインストール
RUN rpm -Uvh http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm && \
rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-6.rpm && \
yum install -y php php-mbstring php-mysql php-gd php-devel php-pecl-xdebug --enablerepo=remi
# php.iniを編集
RUN sed -i -e 's/;date.timezone =/date.timezone = Asia\/Tokyo/' /etc/php.ini && \
sed -i -e 's/display_errors = Off/display_errors = On/' /etc/php.ini && \
sed -i -e 's/post_max_size = 8M/post_max_size = 100M/' /etc/php.ini && \
sed -i -e 's/upload_max_filesize = 2M/upload_max_filesize = 100M/' /etc/php.ini && \
sed -i -e 's/;mbstring.language = Japanese/mbstring.language = Japanese/' /etc/php.ini && \
sed -i -e 's/;mbstring.internal_encoding = EUC-JP/mbstring.internal_encoding = UTF-8/' /etc/php.ini && \
sed -i -e 's/;mbstring.http_input = auto/mbstring.http_input = pass/' /etc/php.ini && \
sed -i -e 's/;mbstring.http_output = SJIS/mbstring.http_output = pass/' /etc/php.ini && \
sed -i -e 's/;mbstring.encoding_translation = Off/mbstring.encoding_translation = Off/' /etc/php.ini
# xdebugの設定を追加
RUN printf "xdebug.max_nesting_level = 1000\n\
xdebug.var_display_max_depth = 3\n" >> /etc/php.d/xdebug.ini
EXPOSE 80
ENTRYPOINT ["/usr/sbin/apachectl"]
CMD ["-DFOREGROUND"]
プロキシVM用のVagrantfile
- boxはSynced FolderにNFSを使いたいのと、Dockerの最新版をサポートしているのでdduportal/boot2dockerを利用
- ホストマシンから直接Dockerを触ることはないので、Docker関係のポートフォワードは無効化。
- 今回使用したイメージだと
vm.config.hostname
が設定できなかったので省略したが、vm.hostsupdater.aliases
の設定だけで特に問題なくhostsが設定された。
proxy.Vagrantfile
Vagrant.configure(2) do |config|
config.vm.define "wordpress_proxy" do |node|
node.vm.box = "dduportal/boot2docker"
node.vm.network :private_network, ip: "192.168.33.20", id: "default-network"
node.vm.network :forwarded_port, guest: 22, host: 2233, id: 'ssh'
node.vm.network :forwarded_port, guest: 2375, host: 2375, id: 'docker', disabled: true
node.vm.network :forwarded_port, guest: 2376, host: 2376, id: 'docker-ssl', disabled: true
node.hostsupdater.aliases = ["wordpress.local"]
node.ssh.insert_key = false
end
end
開発環境2(static.local)
ディレクトリ構成
- srv/
- static.local
- htdocs/
- {案件毎ディレクトリ}
- Vagrantfile
- proxy.Vagrantfile
- Dockerfile
- htdocs/
- static.local
Vagrantfile
- DataコンテナとMySQLコンテナがなくなっただけで、開発環境1と同じ
Vagrant.configure(2) do |config|
# dockerプロバイダの初期設定
config.vm.provider "docker" do |docker|
docker.vagrant_machine = "static_proxy"
docker.vagrant_vagrantfile = "proxy.Vagrantfile"
docker.host_vm_build_dir_options = {
:type => "rsync",
:rsync__exclude => ["htdocs"]
}
end
# Webサーバーコンテナの立ち上げ
config.vm.define "static_web" do |node|
node.vm.synced_folder "htdocs", "/var/www/html", type: "nfs", nfs_export: false, mount_options: ["nolock", "vers=3", "udp"]
node.vm.provider "docker" do |docker|
docker.name = "web"
docker.build_dir = "."
docker.ports = ["80:80"]
end
end
end
Webサーバーコンテナ用のDockerfile
- PHP(とその関連)を抜いた以外は開発環境1と同じ。
FROM centos:6.6
MAINTAINER m.ietomi <jyokyoku@gmail.com>
# TimeZone設定
RUN echo 'ZONE"=Asia/Tokyo"' > /etc/sysconfig/clock
# httpdをインストール
RUN yum -y update && \
yum install -y httpd && \
rm -rf /etc/httpd/conf.d/welcome.conf
# httpd.confを編集
RUN sed -i -e '/<Directory "\/var\/www\/html">/,/<\/Directory>/s/ AllowOverride None/ AllowOverride All/' /etc/httpd/conf/httpd.conf
EXPOSE 80
ENTRYPOINT ["/usr/sbin/apachectl"]
CMD ["-DFOREGROUND"]
プロキシVM用のVagrantfile
- SSH用のポートとホスト名が違うだけで開発環境1とほぼ同じ。
proxy.Vagrantfile
Vagrant.configure(2) do |config|
config.vm.define "static_proxy" do |proxy|
proxy.vm.box = "dduportal/boot2docker"
proxy.vm.network :private_network, ip: "192.168.33.30", id: "default-network"
proxy.vm.network :forwarded_port, guest: 22, host: 2232, id: 'ssh'
proxy.vm.network :forwarded_port, guest: 2375, host: 2375, id: 'docker', disabled: true
proxy.vm.network :forwarded_port, guest: 2376, host: 2376, id: 'docker-ssl', disabled: true
proxy.hostsupdater.aliases = ["static.local"]
proxy.ssh.insert_key = false
end
end
課題
- NFSマウントがMacを再起動する毎に解除されてしまうので、いちいち
vagrant reload
してやる必要がある。(再Buildされてしまうので面倒) - Vagrantfile毎にIPアドレスの設定やポートフォワードの設定をしなくてはならないので、環境が増えたときに管理する手間がかかる