macOSでDocker環境構築

#前置き

エンジニア"見習い"なので、ついこの間までdockerなんて使ってなかったけど使い始めたら感動したのでまとめます。

docker？なにそれ？って方や聞いたことはあるけどよくわからないって方は[こちら](http://www.atmarkit.co.jp/ait/articles/1701/30/news037.html)

今回は、macOSでdocker環境を構築することをゴールとします。

dockerはそもそもLinux環境で動くのものであり、MacやWindowsではVirtualBoxなどVMを立てて動かすものです。macでdockerをサポートするツールがいろいろあるので、今回は2つのアプローチを紹介します。

#Docker for Mac
VirtualBoxにdockerをのせて運用していると、 VMを立ち上げる手間が発生したり、そもそも環境構築が難しく手間もかかります。そんな問題を解決してくれるのが [Docker for Mac](https://www.docker.com/docker-mac) です。

## 1. インストール
下記リンクよりインストールします。無難にStable版で大丈夫です。
https://store.docker.com/editions/community/docker-ce-desktop-mac

## 2. セットアップ
インストールして従っていくとツールバーにクジラが現れますね。
クジラを押すと各種情報や設定、終了の操作ができます。

About Docker
※2018年3月時点の最新バージョン情報です。
<img width="696" alt="スクリーンショット 2018-03-02 15.29.18.png" src="https://qiita-image-store.s3.amazonaws.com/0/240875/11aa9c99-4308-f401-93ca-d7352a7c82e4.png">


Preferences → Advanced
<img width="612" alt="スクリーンショット 2018-03-02 15.29.02.png" src="https://qiita-image-store.s3.amazonaws.com/0/240875/728eb518-56ab-f649-f5be-56a5c83ba757.png">
最初に必要な設定は特にないんですが、CPUとメモリの設定は各自マシンによって決めてください。VirtualBoxは不要ですが、実際にはHyperKitというMacネイティブの仮想化環境が裏で動いています。ここではそれに割り振るCPUとメモリを設定します。

ちなみに筆者のマシンは

- macOS Sierra 10.12.6
- プロセッサ 2GHz 2コア Intel Core i5
- メモリ 8GB 1867MHz LPDDR3

コンテナが複雑になってくると最低でも4GBくらい振らないとキツイです。
筆者はメモリ8GBマシンなので、docker動かしながらIDEとか使っちゃうともうカツカツでブラウジングすら危うくなってきます。AtomでもやばかったのでVSCodeに乗り換えました...


## 3. 実行

ツールボックスのクジラが**Docker is running**となっていればもうdockerコマンドは使えるはずです。

```bash
$ docker version
Client:
 Version:	17.12.0-ce
 API version:	1.35
 Go version:	go1.9.2
 Git commit:	c97c6d6
 Built:	Wed Dec 27 20:03:51 2017
 OS/Arch:	darwin/amd64

Server:
 Engine:
  Version:	17.12.0-ce
  API version:	1.35 (minimum version 1.12)
  Go version:	go1.9.2
  Git commit:	c97c6d6
  Built:	Wed Dec 27 20:12:29 2017
  OS/Arch:	linux/amd64
  Experimental:	true
```

# Docker Toolbox + Dinghy

こちらは無難にVMを立ててdockerを扱うアプローチです。
Docker Toolboxは必要な以下のツールをまとめたパッケージのようなものです。
※各ツールの役割は割愛します

- Docker Client
- Docker Machine 
- Docker Compose
- Docker Kitematic
- Docker Quickstart Termina
- VirtualBox


Docker Toolboxだけでも十分なんですが、今回は**dinghy**というツールも利用します。

Dockerでは基本的にローカルのファイルをマウントすることになりますが、VirtualBoxの共有フォルダ機能は遅いため、Dockerでのマウントもだいぶ遅くなります。
[dinghy](https://github.com/codekitchen/dinghy)はDocker MachineのVolumes機能をNFSマウントに入れ替えてくれて、ファイル共有を高速化することができます。

##1. インストール

[Homebrew](https://brew.sh/index_ja)を使うので入れてない人は入れてください。

```bash:DockerTollboxをインストール
$ brew cask install docker-toolbox
```

```bash:dinghyをインストール
$ brew tap codekitchen/dinghy

$ brew install --HEAD dinghy
```

##2. セットアップ

```bash:dockerホストを作成
$ /usr/local/Cellar/dinghy/4.2.0/bin/dinghy help create

$ dinghy create --disk=30000 --provider virtualbox
```

※ディスクは各自マシンに応じて決めてください

`dinghy create`が終わると環境変数設定してねと促されます。

```bash
export DOCKER_HOST=tcp://192.168.99.101:2376
export DOCKER_CERT_PATH=/Users/xxx/.docker/machine/machines/dinghy
export DOCKER_TLS_VERIFY=1
export DOCKER_MACHINE_NAME=dinghy
```

`.bash_profile`に書くなどしてください。万が一コピペし忘れても

```bash
eval "$(dinghy shellinit)"
```

で設定可能です。

`dinghy up`でDockerホストの起動、`dinghy down`で終了ができるようになるはずです。
Dockerホスト起動状態ならばdockerコマンドが使えるはずです。


#両者の比較

Docker for Mac と Docker Toolbox + Dinghy の2つのパターンを紹介しましたが、ご覧の通り環境構築およびDocker起動の手間は明らかに前者のほうが簡単ですね。
ではなぜDocker Toolboxも紹介したのか？ それはDinghyの説明でも少し触れましたが、ファイル共有の問題です。
Docker for Macは登場当初からファイル共有が遅いというのがずっと問題として挙げられていました。
最近はオプションで[cached](https://docs.docker.com/docker-for-mac/osxfs-caching/#cached)などが出てきて改善されてはいますが、大規模なアプリケーション開発になってくると遅さが目立つようです。

そこで実際にそれぞれのI/O処理速度を計測してみました。
とりあえずマウント領域でダミーファイルを読み書きするコマンドの処理速度で比較してみます。

```bash:write
$ time dd if=/dev/zero of=write_test bs=1k count=100000
```

```bash:read
$ time dd if=read_test of=/dev/null
```

※read_testは1GBのダミーファイル

５回ずつ測った平均で以下のような結果になりました。

|  | write [MB/s] | read [MB/s] |
|:--|:--:|:--: |
| Docker for Mac | 4.94 | 179.2 |
| Docker for Mac (cached) | 5.03 | 227.3 |
| Docker Tollbox + Dinghy | 42.60 | 295.6 |

まだまだDocker Toolbox + Dinghyの勝利って感じですね。

ただし、いろいろ調べてみるとDocker for Macの方が新しく、推奨されている感じなのでこれからDocker始めてみるって方はDocker for Macでいいと思います。

今後のアップデートでファイル共有問題が更に改善されることに期待しましょう。