新しいプロジェクトに入る度に開発環境が変わるので、その度にApacheサーバやら何やらを消しては入れ直しってやるのがいい加減面倒になってきたのでDockerの勉強がてら開発環境構築を自動化してみようという計画
Docker単体での運用でもいいけどDocker for Macは遅いっていう話を聞くし、Windowsだとそもそも10以外門前払いだし...
じゃあVM挟んで運用すればいいよね!( ゚д゚)
けどVMの構築が手間...
そうだ、Vagrantを使おう( ゚д゚)
その前に
Vagrantって?
仮想マシン(VM)の構築を自動化してくれるツール。
VirtualBoxと組み合わせて使う事が多い。
Dockerって?
Linuxコンテナという機能を良しなに使いやすくしたツール。
コンテナのお話とかはちょっと説明が難しいのでこの辺とかこの辺を参考にするとよろし
前提
- 既にある程度開発が進んでるLaravelプロジェクト
- プロジェクトは既にGit管理されている
- 既存の開発環境構築手順があるのでなるべくそれに合わせる
- DBは別途検証用のマシンに入れてるので今回の構成には組み込まない
実行環境
- OS: MacOS 10.12 Sierra
- VirtualBox: 5.0.32
- Vagrant: 1.9.1
- Docker: 17.06.0-ce, build 02c1d87
使用するVM
CentOS7
アプリケーション
- Webサーバ: Apache
- PHP: 7.0.*
- Laravel: 5.3.29
実際にやってみた
構成
path/to/project
├── app/
├── Vagrantfile
├── docker-compose.yml
├── php/
│ ├── Dockerfile
│ ├── mod_rewrite.conf
│ ├── app.conf
│ └── php.ini
└── provision_init.sh
- app: アプリケーションが格納されたフォルダ。これを展開するとLaravelのディレクトリ構成になってる
- Vagrantfile: Vagrantの設定ファイル
- docker-compose.yml: Docker Composeの設定ファイル
- php: Docker Composeで使うフォルダ
- Dockerfile: Dockerイメージを作成するための設定ファイル
- mod_rewrite.conf, app.conf: httpd.confのIncludeとかIncludeOptionalで読み込ませるファイル。httpd.confを直接いじるよりも手間がかからない。
- php.ini: PHPの設定ファイル
- provision_init.sh: Vagrantでの仮想マシン初期構築時に走るスクリプト。この中でDockerをインストールする。
Vagrantの設定
Vagrant.configure("2") do |config|
config.vm.box = "centos/7"
config.vm.hostname = "app.dev"
if ENV['VAGRANT_BRIDGE']
interfaces = %x(VBoxManage list bridgedifs)
re = /Name: +(.*#{ENV['VAGRANT_BRIDGE']}.*)/
if interfaces =~ re
config.vm.network :public_network, bridge: $1
end
else
interfaces = %x(VBoxManage list bridgedifs)
if interfaces =~ /Name: *(.+)\n/
config.vm.network :public_network, bridge: $1
end
end
config.vm.synced_folder "./", "/vagrant", type: "virtualbox", mount_options: ['dmode=777','fmode=775']
config.vm.provider "virtualbox" do |vb|
vb.memory = "1024"
end
config.vm.provision "shell", :path => "provision_init.sh", :privileged => false
config.vm.provision "shell", run: "always", inline: "systemctl restart network.service"
config.vm.provision "shell", run: "always", inline: "service docker start"
end
sudo yum update -y
sudo yum install wget -y
sudo curl -fsSL https://get.docker.com/ | sh
sudo usermod -aG docker vagrant
sudo sh -c "curl -L https://github.com/docker/compose/releases/download/1.15.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose"
sudo chmod +x /usr/local/bin/docker-compose
Dockerの設定
version: '2'
services:
php:
build: ./php
ports:
- '80:80'
volumes:
- /vagrant/app:/app:rw
FROM centos:latest
RUN yum -y update \
&& yum -y install epel-release http://rpms.famillecollet.com/enterprise/remi-release-7.rpm \
&& yum -y install wget httpd git \
&& yum -y --enablerepo=remi-php70 install php php-mbstring php-xml php-pdo php-pgsql \
&& yum clean all
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
COPY php.ini /etc/
COPY app.conf /etc/httpd/conf.d/
COPY mod_rewrite.conf /etc/httpd/conf.modules.d/
RUN mkdir /app
WORKDIR /app
VOLUME /app
RUN groupadd -g 1000 vagrant \
&& useradd -s /bin/bash -u 1000 -g vagrant vagrant \
&& usermod -aG vagrant apache
EXPOSE 80
CMD ["/usr/sbin/httpd", "-D", "FOREGROUND"]
<VirtualHost *:80>
DocumentRoot "/app/public"
<Directory "/app/public">
AllowOverride All
Require all granted
EnableMMAP Off
EnableSendfile Off
</Directory>
</VirtualHost>
LoadModule rewrite_module modules/mod_rewrite.so
起動
$ cd path/to/project
$ vagrant up
$ vagrant ssh
# ここからVM内
$ cd /vagrant
$ docker-compose up -d
VM内で ip a
と叩けばVMに割り当てられたIPアドレスが確認できるので、
そのIPアドレスをブラウザで直接開いてアプリケーションのトップ画面が表示されればクリア。
軽く解説
Vagrantfileについて
config.vm.network :public_network
って設定するとネットワークの割り当てにブリッジアダプタを使用するようになる。
ただそれだけだと Vagrant up
の度に使用するネットワークアダプタを選ばないといけないので環境変数で設定したり良しなにやってくれるようにしてるのが5行目〜16行目。参考記事も参照されたし。
Dockerfileについて
DockerHubに公開されてるphp-apacheイメージがDebianベースだったので今回の要件に合わず。
やむを得ずCentOSのイメージをベースにApacheとPHPを入れる形に。
アプリケーションフォルダのマウント
config.vm.synced_folder "./", "/vagrant", type: "virtualbox", mount_options: ['dmode=777','fmode=775']
volumes:
- /vagrant/app:/app:rw
RUN mkdir /app
WORKDIR /app
VOLUME /app
実マシンの path/to/project
が Vagrantマシン内で /vagrant
としてマウントされ、その中の app
ディレクトリをDockerコンテナ内で /app
としてマウントしている。
こうすることでソースコードの編集を実マシン上で行うことができ、デプロイ作業等をすることなくコンテナに変更が反映される。
但し、これだけだとコンテナ内のApacheアプリケーションがパーミッションエラーを起こす( /app/storage
に書き込みができない)ので、
RUN groupadd -g 1000 vagrant \
&& useradd -s /bin/bash -u 1000 -g vagrant vagrant \
&& usermod -aG vagrant apache
でapacheユーザ(Apacheアプリケーションが使用するユーザ)をvagrantグループに登録してやると、apacheユーザに /app/
以下への書き込み権限が付与される。
(先のVagrantfileで config.vm.synced_folder
に mount_options
を設定しているのもこのため)
まとめとか
今回は既にある程度の規模で開発が進んでるプロジェクトだったのでほぼ自己満で終わってるけど、今後新規開発の話があった時の環境構築のベースにしたい。(実はWindows上での検証ができてないのでそれが先...)
あと使うコンテナが1つだけで、ポートとかマウントの設定のためだけにDocker Composeを使ってるのは勿体無いので、他にもコンテナを乗っけて連携とかできればいいかな。
将来的には検証環境や本番環境のアプリケーションもDockerベースで運用できれば最the高。