Help us understand the problem. What is going on with this article?

vagrant と Docker for Mac で、いい感じの開発環境を構築する

More than 1 year has passed since last update.

仕様

  • web用・DB用と、2つのコンテナを1つのVagrantfileにて定義しています。
  • vagrant up/haltにて2つのコンテナは同時に起動・停止します。
  • ホスト(Mac)上のディレクトリを、web用コンテナ上の(Webサーバーの)ドキュメントルートにマウントし、ホスト(Mac)から直接、編集・更新ができます。

準備

DockerImageの用意

  • WEB用、DB用のDockerイメージを用意します。
  • WEB用はDockerHUB上のcentOSを元に構築
  • DB用はDockerHUB上のmysqlそのまま利用

WEB用Dockerイメージのサンプル

  • Dockerfile
FROM centos:centos6

#Set root password
RUN echo "root:hogehoge" | chpasswd

# Update All
RUN yum update -y

# Install & Add repo
RUN yum install openssh-server -y
RUN rpm -Uvh http://ftp.riken.jp/Linux/fedora/epel/epel-release-latest-6.noarch.rpm
RUN rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-6.rpm
RUN yum --enablerepo=epel install monit -y

# For monit config
ADD monit/sshd.conf  /etc/monit.d/sshd.conf
ADD monit/apache.conf /etc/monit.d/apache.conf
RUN sed -ri 's/use address localhost/use address 0.0.0.0/g' /etc/monit.conf
RUN sed -ri 's/allow localhost/# allow localhost/g' /etc/monit.conf

# Install PHP5.6 & Apache
RUN yum --enablerepo=remi-php56 install php php-devel php-gd php-xml php-mbstring php-opcache php-mcrypt php-mysqlnd php-pecl-apcu php-pecl-memcached -y

# Apache config
RUN sed -ri 's/#NameVirtualHost *:80/NameVirtualHost *:80/g' /etc/httpd/conf/httpd.conf
ADD apache/00_virtualhost.conf /etc/httpd/conf.d/00_virtualhost.conf

# Clear yum cache
RUN yum update all -y

# for ssh
EXPOSE 22
# for WEB
EXPOSE 80
# for monit
EXPOSE 2812
CMD ["/usr/bin/monit", "-I", "-c", "/etc/monit.conf"]
  • monit/sshd.conf
check process sshd with pidfile /var/run/sshd.pid
    start program = "/sbin/service sshd start"
    stop program = "/sbin/service sshd stop"
  • monit/apache.conf
check process apache with pidfile /var/run/httpd/httpd.pid
    start program = "/sbin/service httpd start"
    stop program = "/sbin/service httpd stop"
  • apache/00_virtualhost.conf
<VirtualHost *:80>
    ServerName   localhost
    ErrorLog     /var/log/httpd/localhost-error_log
    CustomLog    /var/log/httpd/localhost-access_log common

    DocumentRoot /var/www/public_html
    <Directory "/var/www/public_html">
      AllowOverride All
      Options FollowSymLinks
      Options -Indexes
    </Directory>
</VirtualHost>

DockerImageの作成

docker build -t web:apache ./ --no-cache=true
docker pull mysql:5.6

Vagrantfile

Vagrant.configure("2") do |config|

  config.vm.define "db01" do |node|
    node.vm.provider "docker" do |d|
      d.force_host_vm = false
      d.remains_running = false
      d.name = "db01"
      d.image = "mysql:5.6"
      d.ports = ["3306:3306"]
      d.env = {
        MYSQL_ROOT_PASSWORD: "root"
      }
    end
  end

  config.vm.define "web01" do |node|
    node.vm.synced_folder "public_html", "/var/www/public_html"
    node.vm.provider "docker" do |d|
      d.force_host_vm = false
      d.remains_running = false
      d.name =  "web01"
      d.image = "web:apache"
      d.ports = ["22122:22","80:80","2812:2812"]
      d.link "db01:db01"
    end
  end

end

解説

[config.vm.define "db01" / "web01" do |node|]

  • 複数のコンテナを立ち上げるため、各コンテナを定義

[node.vm.provider "docker" do |d|]

  • Vagrant DockerProvider の指定

[d.force_host_vm = false]

  • Vagrant DockerProvider を利用する場合、Mac環境ではDockerホスト用のVagrantBox(boot2docker)が自動的にダウンロード・起動されます。今回はDocker for Mac を利用するためfalseとし、Boxを利用しません。詳しくはこちら

[d.ports = ["3306:3306"] / ["22122:22","80:80","2812:2812"]]

  • 各コンテナで[フォワード先のポート:(コンテナで)解放するポート]を指定 

[node.vm.synced_folder "public_html", "/var/www/public_html"]

  • ホスト(Mac上)のVagrantfileがあるカレントディレクトリ内のpublic_htmlを、コンテナ上の/var/www/public_htmlにマウント
  • Vagrant を利用すると、Mac上のカレントディレクトリがコンテナ上の/vagrantにマウントされますが、あえて明示的に指定

[d.link "db01:db01"]

  • web01コンテナとdb01をリンク
  • web01からは、ホスト名db01にてdb01に接続が可能

[MYSQL_ROOT_PASSWORD: "root"]

  • MySQLでのrootユーザーのパスワードの設定

その他

  • web01のDockerイメージは、Apacheのドキュメントルートを/var/www/public_htmlと設定

コンテナの起動

  1. Vagrantfileと同じディレクトリ内にpublic_htmlを用意
  2. vagrant up --no-parallelを実行します。
    1. Vagrantfile内に複数のVM(コンテナ)が記載されている場合、Vagrantは標準でパラレル(同時進行)でVMを起動させます。 今回、コンテナ間のリンクを利用するため、web01コンテナよりも先にdb01コンテナの起動が完了している必要があります。 そのため、--no-parallelを付け、コンテナを順に起動させます。
    2. db01コンテナをVagrantfile上で先に書くこと。
    3. 詳しくはこちら
  3. ブラウザからlocalhostを開くとpublic_htmlに設置したファイルが観れます。
  4. PHPプログラム(web01コンテナ)からDBを参照する場合は、ホスト名にdb01を指定ください。
  5. ホスト(Mac)上からDBを参照する場合は、127.0.0.1:3306にて参照可能です。

まとめ

今までのboot2dockerイメージを利用した、VagrantでのDockerコンテナの利用の場合、Mac上のディレクトリをDockerホストと共有し、Dockerコンテナにマウントする手順となっていました。
Docker for Mac を利用すれば、Mac上のディレクトリを直接Dockerコンテナにマウント出来るようになりシンプルな構成となりました。
Vagrantを利用することで、複数のコンテナの起動停止が1つのコマンドで可能です。
おそらくDocker for Windows でも流用可能かと思います。

追記

その後、しばらく使ってみていくつかの軽微な不具合があります。

synced folder が毎回更新されていると認識される

2回目以降の起動時に、synced folderが更新されていると認識され、コンテナの起動時にコンテナが再作成されている。

$ vagrant up --no-parallel
Bringing machine 'db01' up with 'docker' provider...
Bringing machine 'web01' up with 'docker' provider...
==> db01: Starting container...
==> db01: Provisioners will not be run since container doesn't support SSH.
==> web01: Vagrant has noticed that the synced folder definitions have changed.
==> web01: With Docker, these synced folder changes won't take effect until you
==> web01: destroy the container and recreate it.
==> web01: Starting container...
==> web01: Provisioners will not be run since container doesn't support SSH.
  • 原因は謎です。

コンテナのステイタスが正しく反映されない

2回目以降の起動時にvagrant global-statusにて正しくコンテナの起動状態が取得できません。

$ vagrant global-status
id       name    provider      state       directory
------------------------------------------------------------------------------------------
0671d78  web01   docker        stopped     /Users/hogeuser/Documents/vagrant/docker_webdb
d69b340  db01    docker        stopped     /Users/hogeuser/Documents/vagrant/docker_webdb

※実際にはコンテナは起動している

$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES
5e5e7816bee9        web:apache24        "/bin/sh -c '/usr/sbi"   11 minutes ago      Up 7 minutes        0.0.0.0:80->80/tcp       web01
20845bd63177        mysql:5.6           "docker-entrypoint.sh"   12 minutes ago      Up 7 minutes        0.0.0.0:3306->3306/tcp   db01

その際は$ vagrant global-status --pruneコマンドで正しいステイタスが取得できます。

$ vagrant global-status
id       name    provider      state       directory
------------------------------------------------------------------------------------------
0671d78  web01   docker        running     /Users/hogeuser/Documents/vagrant/docker_webdb
d69b340  db01    docker        running     /Users/hogeuser/Documents/vagrant/docker_webdb
jey0taka
お餅の妖怪
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away