Vagrant+CoreOS+DockerでホストOSに依存しないローカル開発環境をつくる

ここ最近、仮想開発環境界隈ではDockerが流行っていますが、どうしてもMacだと動くけどWindowsだと動かない…とかどうしてもホストOSの環境に依存する不具合が出てきてしまいます。
もうホストOSに依存するような開発環境は嫌だ！
ということで、コマンド一発で仮想開発環境ができるような仕組みをVirtualBox+Vagrant+CoreOS+Dockerで実現してみました。

# 構成
ホストOS（Win or Mac）にVirtualBoxを置き、その中にCoreOSのマシンを立て、さらにその中にDockerのコンテナが並んでいるような構成を作ります。
![Untitled.png](https://qiita-image-store.s3.amazonaws.com/0/2781/0418c9f3-e302-e3c1-e64e-b0e226f1107e.png)

# フォルダ構成
`app/var/public_html` の中にプロダクトのソースコードが入るイメージです。
今回は複数のサブドメインでアクセスするようなサービスだったのでプロキシーサーバーも立てました。
<img width="279" alt="Desktop.png" src="https://qiita-image-store.s3.amazonaws.com/0/2781/0f867563-667a-a615-4bf3-e28ac4969859.png">



# Vagrantの構築
Vagrantfileでdocker-composeのインストールやdockerの起動、共有フォルダのマウントをやっていきます。

```bash:Vagrantfile
# -*- mode: ruby -*-
# # vi: set ft=ruby :

Vagrant.configure("2") do |config|
  config.ssh.insert_key = false
  config.vm.box = "coreos-alpha"
  config.vm.box_url = "https://storage.googleapis.com/alpha.release.core-os.net/amd64-usr/current/coreos_production_vagrant.json"

  config.vm.provider :virtualbox do |v|
    v.check_guest_additions = false
    v.functional_vboxsf     = false
    v.memory = 2048
    v.cpus = 2
  end

  if Vagrant.has_plugin?("vagrant-vbguest") then
    config.vbguest.auto_update = false
  end

  config.vm.network :private_network, :ip => "192.168.33.10"

  # docker-composeのインストール
  config.vm.provision :shell, inline: <<-SHELL
    mkdir -p /opt/bin
    curl -L https://github.com/docker/compose/releases/download/1.12.0/docker-compose-`uname -s`-`uname -m` > /opt/bin/docker-compose
    chmod +x /opt/bin/docker-compose
  SHELL

  # coreosの自動アップデートを無効にする
  config.vm.provision :shell, inline: <<-SHELL
    sudo systemctl stop update-engine 
  SHELL

  # 共有フォルダの作成
  config.vm.synced_folder "./share", "/home/core/share", :nfs => true, :mount_options => ["nolock,vers=3,udp"] 

  config.vm.provision :shell, privileged: false, inline: <<-SHELL
    cd ~/share/proxy && docker-compose build
    cd ~/share/app && docker-compose build
  SHELL

  # docker起動
  config.vm.provision "shell", run: 'always',privileged: false, inline: <<-SHELL
    cd ~ && docker network create --driver bridge proxy
    cd ~/share/proxy && docker-compose up -d 1>&2
    cd ~/share/app && docker-compose up -d 1>&2
  SHELL
  
  config.ssh.forward_agent = true

  # プロジェクトのClone 
  config.vm.provision "shell", privileged: false, inline: <<-SHELL
    echo -e "Host gitlab.com" > ~/.ssh/config
    echo -e "    StrictHostKeyChecking no" >> ~/.ssh/config
    sudo mkdir -p ~/share/app/var/public_html
    cd ~/share/app/var/public_html && git clone git@gitlab.com:hogehoge
  SHELL

end
```

# アプリケーション系Dockerの構築
WebサーバーとDBサーバー、memcachedのコンテナを作成します。今回はphpMyAdminも入れてみました。

```bash:app/docker-compose.yml
version: '2'

services:
  mysqldata:
    image: busybox
    container_name: my_db_data
    volumes:
      - /var/lib/mysql
  # mysql
  mydb:
    image: mysql:5.6
    container_name: my_db
    ports:
      - "3306:3306"
    environment:
      MYSQL_ROOT_PASSWORD: root
    volumes:
      - ./files/mysql_conf:/etc/mysql/conf.d
      - ./var/public_html/sql:/docker-entrypoint-initdb.d
    volumes_from:
      - mysqldata
  # web
  myweb:
    build: ./web
    image: web:24
    container_name: my_web
    environment:
      VIRTUAL_HOST: hoge.dev
      VIRTUAL_PORT: 80
    links:
      - mydb:mydb
      - memcached
    volumes:
      - ./var/public_html:/var/www/public_html
      - ./var/logs:/var/log/httpd
      - ./files/apache_conf/vhosts.conf:/etc/httpd/conf.d/vhosts.conf
      - ./files/php_conf/php.ini:/etc/php.ini
  # memcacheの構築
  memcached:
    image: memcached
  # phpMyAdminの構築
  phpmyadmin:
    image: phpmyadmin/phpmyadmin
    environment:
      - PMA_ARBITRARY=1
      - PMA_HOST=mydb
      - PMA_USER=root
      - PMA_PASSWORD=root
    links:
      - mydb
    ports:
      - 8080:80
networks:
  default:
    external:
      name: proxy
```
Apacheの設定ファイルやphp.iniもgit管理してそこからDockerに渡すようにしてしまいます。
データベースdumpデータも、DBコンテナの`/docker-entrypoint-initdb.d`配下に置くことによってコンテナ構築時に、自動的にインポートしてくれます。

# プロキシーDockerの構築
Nginxでプロキシサーバーを構築します。

```bash:proxy/docker-compose.yml
version: "2"
services:
  proxy:
    image: jwilder/nginx-proxy
    container_name: proxy
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - /var/run/docker.sock:/tmp/docker.sock:ro
      - ./certs:/etc/nginx/certs:ro
      - ./conf.d:/etc/nginx/conf.d
    restart: always
    logging:
      options:
        max-size: 5m
        max-file: "10"

networks:
  default:
    external:
      name: proxy
```

ここまでできれば、あとはhostsに `192.168.33.10 hoge.dev` を記載して `Vagrant up` すれば、 http://hove.dev で開発環境が見れるようになります。

# まとめ
CoreOSはコンテナの利用に特化したOSなので、Dockerととても相性が良いです。
そして、今回はDocker側から見たホストマシンはCoreOSなので、よくありがちなWindowsで動かない問題が起きず、みんなハッピーになれますね。