OSXでDockerを超高速化するdinghy

【追記 2016/06/21】
[Docker for Mac](https://docs.docker.com/docker-for-mac/)がリリースされました。これでVirtualBoxを使う必要はなくなったので、この記事にあるdinghyを導入する必要はありません。

---

OSXでDockerを使うときには、VirtualBox + Docker Machineを使う事が多いと思います。しかし、VirtualBoxの共有フォルダ機能は凄く遅いため、その上で動くDockerも共有Volumesを使うと遅くなるという問題があります。

Vagrantの場合には、NFSマウントを使う事で早くすることができますが、Docker Machineにはその機能がありません。

そこで、OSXのDocker MachineのVolumes機能をNFSに入れ替えてくれる[dinghy](https://github.com/codekitchen/dinghy)を試してみました。

## codekitchen/dinghy: faster, friendlier Docker on OS X
https://github.com/codekitchen/dinghy

- Volume sharing機能でNFSを使い高速化します。VMWareで30秒、Virtualboxで90秒かかる中規模のRailsアプリの起動が5秒に短縮されます。
- ファイルの変更イベントも通知されるのでguardやwebpackなどの変更検知アプリが正しく動くようになります。
- build-in DNSとHTTP proxyを使いコンテナ内に容易にアクセスできます。

## インストール

インストールは簡単で、homebrewやpackageでdockerをインストールしたあと、下記の様なコマンドを実行するだけです。

```sh
brew tap codekitchen/dinghy
brew install dinghy
dinghy create --provider virtualbox
```

これで完了です。もう既存のDocker Machineを使わないと言うのであれば、`docker-machine rm default -y`してください。

このあとは、`docker-machine`コマンドの代わりに`dinghy`コマンドを使って操作します。なぜかコマンド体系が微妙に違うので気をつけて下さい。

```
$ dinghy
Commands:
  dinghy create          # create the docker-machine VM
  dinghy destroy         # stop and delete all traces of the VM
  dinghy halt            # stop the VM and services
  dinghy help [COMMAND]  # Describe available commands or one specific command
  dinghy ip              # get the VM's IP address
  dinghy nfs             # start or stop the internal nfs daemon
  dinghy restart         # restart the VM and services
  dinghy shellinit       # returns env variables to set, should be run like $(dinghy shellinit)
  dinghy ssh [args...]   # ssh to the VM
  dinghy status          # get VM and services status
  dinghy up              # start the Docker VM and services
  dinghy upgrade         # upgrade the boot2docker VM to the newest available
  dinghy version         # display dinghy version
```


私の環境では起動時に下記の様なエラーが出たので、証明書を再生成しました。

```sh
$ dinghy start
docker: An error occurred trying to connect: Post https://192.168.99.100:2376/v1.22/containers/create?name=dinghy_http_proxy: x509: certificate is valid for 192.168.99.101, not 192.168.99.100.
$ docker-machine regenerate-certs dinghy
```

## 環境設定

私は`.zshrc`を複数のマシンで共有しているので、下記の様に変更しました。

これでdinghyの有無を問わず`dm-start`でDocker Machineを起動できます。


```sh
# Docker
alias d="docker"
alias dc="docker-compose"
if [ -s "/usr/local/bin/dinghy" ] ; then
  alias dm="dinghy"
  alias dm-start="dinghy start && eval \"\$(dinghy shellinit)\""
  alias dm-restart="dinghy restart && eval \"\$(dinghy shellinit)\""
  alias dm-env="eval \"\$(dinghy shellinit)\""
else
  alias dm="docker-machine"
  alias dm-start="docker-machine start default && eval \"\$(docker-machine env default)\""
  alias dm-restart="docker-machine restart default && eval \"\$(docker-machine env default)\""
  alias dm-env="eval \"\$(docker-machine env default)\""
fi

if [ -s "/usr/local/bin/docker-machine" ] ; then
  dm-env > /dev/null 2>&1
fi
```

## 使い方

あとは今までと同じように動かせます。

一度起動してしまえば、違いを気にすることはほとんどないでしょう。

高速化も大きな恩恵ですが、それよりもGuardやwebpackが変更検知してくれるようになったことが一番の恩恵でした。

## 問題点

問題点としては、dinghyが80番ポートを使うので、80番にマッピングできないことです。なぜ80番を使うんだ。。。。せめて81番とかつかってくれればいいのに・・・

追記: コメントでhttp proxy機能を切れば80番が解放されると教えてもらいました。

volume mount配下でchownができないので `npm install` などが転ける問題があります。仕様なのでどうしようもないようです。

https://github.com/codekitchen/dinghy/issues/17

下記の様にして凌ぎました。

```sh
cp /usr/src/app/package.json /root/
cd /root && npm install -q
rsync -rlzuIO --ignore-errors /root/node_modules/ /usr/src/app/node_modules > /dev/null 2>&1
rm -rf /root/node_modules /root/package.json
```

## 執筆時の環境

```sh
$ docker -v
Docker version 1.10.1, build 9e83765
$ dinghy -v                             
Dinghy 4.2.0
```

## 宣伝

DevOps好きだ！と思っている方、一緒に働きませんか？ [3,000万人の予約を支えるDevOpsエンジニア募集！](https://www.wantedly.com/projects/27205)でお待ちしています。

よければ、[トレタメンバーのQiita](http://qiita.com/organizations/toreta)も見ていって下さい。