dnsdock の活用：Wocker でも同時に複数のサイトを開発出来るようにする

[dnsdock の Docker イメージを小さくする - Qiita](http://qiita.com/A-I/items/995ad9251d9377df6b64) でご紹介した dnsdock を使って何か出来ないかと考えていたのですが、同時に１サイト（コンテナ）しか起動できない Wocker をサンプルに、「複数コンテナを立ち上げて自動的に名前解決してローカルマシンからアクセス出来るようにする」ことを思いつきました。

レシピは大きく分けて３つ。

1. Wocker にパッチを当てて複数のコンテナを起動出来るようにする。
2. dnsdock コンテナを立ち上げる。
3. ローカルマシンの DNS Resolver とルーティングの設定をする。

１．に関しては Wocker を取り上げていますが、dnsdock の利用は Wocker でなくてもどんなコンテナにも応用可能です。
３．に関しては Mac OSX を前提としていますが、同様の設定が Windows や他の OS でも可能であれば同じようなことが出来るはずです。

下記の解説は一部簡略化して手入力で行っていますが、完全版は
https://github.com/ailispaw/wocker/tree/wocker-multi
を参照して下さい。下記の作業は全て自動的に行われます。
（３．の設定には `vagrant-triggers` プラグインが必要になります）

## Wocker について

Docker-based rapid development environment of WordPress
http://wckr.github.io/

Wocker は、Docker を使って WordPress の開発環境を高速に構築するツールです。
その Docker ホスト VM（wocker VM）は Vagrant を使って起動され、そのベースとなる box に私が開発している [Docker ホスト用軽量 OS](https://atlas.hashicorp.com/ailispaw/boxes/docker-root) を採用して頂いた関係で Watch させて頂いております。

[VirtualBox](http://www.vagrantup.com/) と [Vagrant](https://www.virtualbox.org/) がインストールされていれば、

```bash
$ git clone https://github.com/wckr/wocker.git && cd wocker
$ vagrant up
$ echo "10.0.23.16 wocker.dev" | sudo tee -a /etc/hosts
$ open http://wocker.dev
```

だけで、ローカルマシンのブラウザでサイトが確認出来るようになります。
（`vagrant-hostsupdater` プラグインがインストールされていれば、`/etc/hosts` の設定は自動的に行われます）
サイトのコードはローカルマシンの `./data` ディレクトリ内に保存されて、VM／コンテナと同期されているので、ローカルでそのまま開発が出来るようになっています。


## １．Wocker にパッチを当てる

###  `wocker` スクリプトへのパッチ
Wocker の内部では `wocker` というスクリプトが `docker run` を使って WordPress コンテナを起動しているのですが、オプションに `-p 80:80 -p 3306:3306` が指定されており、wocker VM のポートを専有してしまうので、同じコンテナを同時に複数起動することは出来ません。
これを削除してしまいます。

```bash
$ vagrant ssh
Welcome to DockerRoot version 1.2.11, Docker version 1.9.1, build 66c06d0-stripped
wocker ~ $ sed -i 's/-p 80:80 -p 3306:3306//g' /opt/bin/wocker
```

逆に、これによって VM の IP アドレスである `10.0.23.16` (wocker.dev) ではアクセス出来なくなってしまいます。そこで、`dnsdock` の出番となります。

### `wocker/wocker` Docker イメージ／ WordPress コンテナへのパッチ

WordPress コンテナのベースとなるイメージ `wocker/wocker` には、既に WordPress と共に、必要なツールや環境設定が予めパッケージングされています。前提としてサイトの URL が `http://wocker.dev` に固定されている為、このままでは、同時に起動出来たとしても、異なるサブドメインを使って複数のサイトにアクセスしても表示がうまくいきません。
これを各コンテナの起動直後に `docker exec` を使って変更してしまいます。

```bash
wocker ~ $ wocker run --name <container-name>
wocker ~ $ docker exec <container-name> wp option --allow-root update siteurl http://<container-name>.wocker.dev
wocker ~ $ docker exec <container-name> wp option --allow-root update home http://<container-name>.wocker.dev
```

## ２．[dnsdock](https://github.com/tonistiigi/dnsdock) コンテナを起動する

```bash
wocker ~ $ docker run -d --name dnsdock -v /var/run/docker.sock:/var/run/docker.sock -p 53:53/udp ailispaw/dnsdock /dnsdock -domain=dev
```

- `/var/run/docker.sock` をマウントすることにより、ホスト VM 上の Docker リソースにアクセス出来るようになり、自動的にコンテナを認識して DNS を設定します。
- `53:53/udp` で DNS ポートをホスト VM にマッピングすることにより、ホスト及び外部から `10.0.23.16` で DNS サーバーにアクセス出来るようになります。
- 最後の `-domain=dev` はドメイン名を `.dev` にするオプションで、省略すると `.docker` になります。

これらの設定から、dnsdock は `<container-name>.<image-name>.<domain>` で特定のコンテナにアクセス出来るように DNS を自動的に設定します。
例えば、Wocker の `vagrant up` 直後は `wocker/wocker` イメージを使って `wocker` という名前のコンテナが自動的に起動されるようになっているので、そのコンテナには`wocker.wocker.dev` でアクセスすることになります。

```bash
wocker ~ $ nslookup wocker.wocker.dev 10.0.23.16
Server:    10.0.23.16
Address 1: 10.0.23.16

Name:      wocker.wocker.dev
Address 1: 172.17.0.3 wocker.dev
wocker ~ $ exit
logout
$ nslookup wocker.wocker.dev 10.0.23.16
Server:		10.0.23.16
Address:	10.0.23.16#53

Non-authoritative answer:
Name:	wocker.wocker.dev
Address: 172.17.0.3
```

## ３．ローカルマシンの DNS Resolver とルーティングの設定をする

上記で下準備が出来ました。
残りはローカルマシン側の設定です。

### 特定のドメインに対して DNS Resolver を指定する

Mac OSX の場合 `/etc/resolver` ディレクトリにドメイン名のファイルを作り、その中に DNS サーバーのアドレスを書き込むことによって、その特定のドメイン名のアドレス解決はその DNS サーバーを使用するようになります。

```bash
$ sudo mkdir -p /etc/resolver
$ echo "nameserver 10.0.23.16" | sudo tee /etc/resolver/dev
```

### コンテナのアドレスを VM にルーティングする

この場合、具体的には、Docker のデフォルトのコンテナのアドレス・レンジ `172.17.0.1/16` を `10.0.23.16` にルーティングすることになります。

```bash
$ sudo route -n add -net 172.17.0.0 10.0.23.16
```

以上で、ローカルマシンのブラウザから `http://wocker.wocker.dev/` にアクセス出来るようになります。

## 複数のコンテナの起動

WordPress （wocker/wocker）コンテナを別名で起動して上記１．のように `docker exec` でパッチを当てるとその名前でブラウザからアクセス出来るようになります。

https://github.com/ailispaw/wocker/tree/wocker-multi
では `wocker-multi` というスクリプトを用意して、その部分を自動化していますので、

```bash
$ vagrant ssh -c "wocker-multi <container-name>"
$ open http://<container-name>.wocker.dev
```

だけで、そのサイトを見ることが出来ます。
サイトのデータは `./data/<container-name>` に保存されます。

## 長くなってしまいましたが、
肝心な部分は２．の dnsdock コンテナの起動だけで、コンテナの名前ーアドレス解決が自動的に出来るようになるってところです。
単一の Docker ホスト内に制限はされますが、Wocker にかぎらず、他のコンテナにも応用出来ます。
ローカルの開発には十分有効なのではないでしょうか。

それではまた。