Mac版 Docker Toolbox を使ってみました


# 20171128 追記 (2017年末時点でのMac / Win用Docker）

2016年半ば時点で、Mac版のDocker利用では2つの方式が利用できました。
こちらに加えて、2017年末時点ではWindows版についても2つ方式があります。（厳密に言うと、もっとありますが簡単に始められるタイプとして2つずつ）

記事が古くなっているところにご訪問下さった方に申し訳ないので、新旧（？）の仕組みの違いを書いた簡単な図を載せておきます。
それぞれ、Mac版とWindows版になります。

## Mac版のDocker

![23844695_1537167039697076_617192453126326122_n.jpg](https://qiita-image-store.s3.amazonaws.com/0/27976/c2af9a1b-659d-2869-79b6-6bc9121ce78b.jpeg)

## Windows版のDocker

2017年末時点で提供されている Docker for Windowsだと、Hyper-Vを利用し、その上でDockerホストとして働くLinux (MobyLinux) の仮想マシンが立ち上がります。
さらに、Wondowsのdos（cmd.exe)やPowerShellから、直接dockerコマンドを叩くことができます。

![23905459_1537182236362223_457449885781614459_n.jpg](https://qiita-image-store.s3.amazonaws.com/0/27976/d1de7e53-56a8-3d60-f619-67d0b6bc4564.jpeg)

参考になりましたら幸いです。

# 20160630 追記 (はじめにお読みください）

2016年6月には、Docker純正の **Docker for Mac** というパッケージのβ版がリリースされています。

公式サイトの https://docs.docker.com でも、トップページにDocker for Mac, Docker for Windowsといった新しいパッケージのリンクが掲載されています。ただし、6/30時点では、画面上部に public beta の文字が入っていますので、ご注意下さい。

Docker for Macでは、Dockerホストの軌道にVirtualBoxではなく、HyperKitというMacネイティブの仮想化環境を利用しています。こちらの記事の仮想化環境とは異なりますので、ご注意下さい。（ただし、基本的なdocker-machineコマンドやKitematicは同じように使えます）
しばらくDocker for Macを利用してみて、また気がついた点がありましたら、関連する記事を書こうと思います。

こちらの記事で紹介している Docker Toolboxは、以下のリンクからアクセスできます。

* https://docs.docker.com/toolbox/toolbox_install_mac/

# はじめに

以前、Virtualbox (Vagrant利用) のUbuntuに、Docker用のVMを立てて、なんとなく触ってはみたものの...。
なんだかんだでVirtualBox / Vagrantで用は済んでいたので、あまり学習しないまま放置しておりました。

- Ref. [Dockerfileを試す](http://qiita.com/akiko-pusu/items/f32dcf7940dc05fcffc4)

さて、それから一年以上....。今や回りの皆さんは普通にDocker使っています。
これではいかん!と思って、箱庭環境を改めて整えようと思った次第です。


## 今回やること / やらないこと

いつも通り長めのメモなので、やること・やらないことを簡単に上げます。

- やること
 - Mac版 Docker Toolboxのインストール
  - 起動の仕組みの確認
 - 管理用コンソールとGUIツールの説明
 - まとめ / 今回はまったポイントなど
 
- やらないこと
 - Dockerそのものについての詳しい説明
 - ベースになっているVirtualBox, Vagrantについての説明

すでにDocker Toolboxについてはたくさん情報がありますので、ご容赦くださいませ。


## Docker Toolbox について

簡単に言うと、仮想VMでDocker用のホストを立ち上げ、Docker環境を簡単に利用できるようにしたツールです。
Mac版・Windows版が出ています。

## インストールしてみる

まずは [Docker Toolbox](https://www.docker.com/toolbox) から、Mac版のインストーラをダウンロードして、インストールの上、起動します。

アプリケーションフォルダ側に、アイコンとして表示されるものは以下２つです。

- Kitematic（GUIツール）
 - Dockerコンテナを一覧したり、設定を調整したりできるGUIツールです
 - Docker Hubからイメージを追加したりできます 
- Docker Quickstart Terminal
 - クリックすると、Docker用ホストを起動
 - さらに、Mac上から操作するための環境変数などを設定した上で、ターミナルが起動 

![run-docker-toolbox.jpg](https://qiita-image-store.s3.amazonaws.com/0/27976/3ccd3d28-8304-a803-ce8a-488dda5ccbf1.jpeg "run-docker-toolbox.jpg")

さらに、実際にインストールされるものは、[本家](http://docs.docker.com/mac/step_one/) の記載に書いてありますが、ざっくりこんな感じです。

- VirtalBox（アプリケーション -> Dockerフォルダではなく、VirtualBoxとして入ります）
 - Dockerホストを仮想環境で動かすため
- docker-machine
 - Mac上からDocker用ホストを管理するためのコマンドラインツール
 - Docker用ホストの起動/停止/作成やssh、scpでのアクセスができるようになります
- docker
 - 基本のdocker用コマンドラインツール 
 - 本来はDocker用ホスト内で利用しますが、Macのターミナルから直接操作できるようになっています 
- [docker-compose](https://docs.docker.com/compose/)
 - アプリケーションを複数のDockerコンテナを使って構成したい場合に便利なツール 
- Dockerを操作するために必要なシェルもろもろ


※ docker-compose に関しては、そこまで使いこなせていないので扱えませんが、こちらの記事を参考にさせていただきました！

- [docker-composeを使うと複数コンテナの管理が便利に](http://qiita.com/y_hokkey/items/d51e69c6ff4015e85fce)

## Docker QuickStart Terminalを起動してみる

Docker Quickstart Terminal を起動すると何が起こるかというと、なにやらターミナルが立ち上がり、ゴニョゴニョ動いた挙げ句、見慣れたDockerのアスキーアートが表示されました！

```
 # dockerコマンドが利用できるようにするためのおまじないをかける
bash --login '/Applications/Docker/Docker Quickstart Terminal.app/Contents/Resources/Scripts/start.sh'

# Dockerホスト用のマシンを立ち上げる処理が走る
Machine default already exists in VirtualBox.
Starting machine default...
Started machines may have new IP addresses. You may need to re-run the `docker-machine env` command.
Setting environment variables for machine default...

# しばらくすると以下のアスキーアートが...

                        ##         .
                  ## ## ##        ==
               ## ## ## ## ##    ===
           /"""""""""""""""""\___/ ===
      ~~~ {~~ ~~~~ ~~~ ~~~~ ~~~ ~ /  ===- ~~~
           \______ o           __/
             \    \         __/
              \____\_______/


docker is configured to use the default machine with IP 192.168.xxx.xxx
For help getting started, check out the docs at https://docs.docker.com

%
```

同じターミナルで、簡単に試してみます。

``` 
# ためしに dockerコマンドを打つ
% docker -v
Docker version 1.8.2, build 0a8c2e3

% docker version
Client:
 Version:      1.8.2
 API version:  1.20
 Go version:   go1.4.2
 Git commit:   0a8c2e3
 Built:        Thu Sep 10 19:10:10 UTC 2015
 OS/Arch:      darwin/amd64

Server:
 Version:      1.8.2
 API version:  1.20
 Go version:   go1.4.2
 Git commit:   0a8c2e3
 Built:        Thu Sep 10 19:10:10 UTC 2015
 OS/Arch:      linux/amd64

```

これで、Mac上のターミナル（ホストもMac上) から、Docker関連のコマンドが実行できるようになりました。

## なんで透過的にMacのターミナルから使えるの？

今まで（というか、わたしの試した範囲で）は、

- VirtualBox上のUbuntuにsshでログインする
- Macでは直にDockerを動かせないので、Ubuntuを立ててDockerのホストにする 
- Dockerホスト内のUbuntuの中で、Docker関連の操作をする
 
といった感じでしたが、Ubuntuに入らなくともMac上からdockerコマンドが利用できます。

『あれれ？』と思ったのですが、 [Learn the key concepts](https://docs.docker.com/installation/mac/#learn-the-key-concepts-before-installing) に、そのあたりの仕組みが書いてありました。

どうやら、

- VirtualBox上に、Dockerホスト用の boot2docker ~~Ubuntu~~ を起動させる
 - ディストリビューションはboot2dockerですが、基本はLinuxベースの母艦を使う点は同じ
 - ※ 初回の起動時に、"default" というマシン名でVMを勝手に作成
- Mac上のdockerコマンドが、boot2docker上のDockerデーモンに対して透過的にマップされる
 - DockerホストはTCPで待ち受け (デフォルト 2376)
 - 接続に当たっては [Docker over TLS](https://docs.docker.com/articles/https/)を利用

という流れで、さもMac上にローカルにDockerが動いている、かのように操作出来るらしいです。

TCP経由でDockerを操作できる仕組みは、このツールがよしなに設定してくれております。
(#自分では絶対に設定できません.....)

## docker-machine コマンドを使ってみる

さて、Dockerそのものをいじるのではなく、docker-machine について。

VirtualBoxやVagrant を使ってDockerホストを起動させているのは間違いないのですが、vagant ssh みたいに、Dockerホストにssh するにはどうすればいい...? と思ったところ、これも docker-machineコマンドを使う事が出来ました。

- docker-machine create <マシン名>
 - Dockerホスト用の仮想マシンを作成できる
 - Toolboxの初回起動時に、背後でこのコマンドで"default"というマシンが作成される
 - 微妙に構成の違うDockerホストを作成できる

- docker-machine ssh <マシン名>
 - vagrant ssh のような感じで、Dockerホストにsshできる
 - パスワードは聞かれない
- docker-machine scp ローカルのディレクトリやファイル マシン名:scpしたいパス
 - Mac上のファイルをDockerホストにscpできる
 - 複数Dockerホストがある場合、machine to machine も可能？ 

では、実際に docker-machine ssh default してみます。
 
 ```
 % docker-machine ssh default
                        ##         .
                  ## ## ##        ==
               ## ## ## ## ##    ===
           /"""""""""""""""""\___/ ===
      ~~~ {~~ ~~~~ ~~~ ~~~~ ~~~ ~ /  ===- ~~~
           \______ o           __/
             \    \         __/
              \____\_______/
 _                 _   ____     _            _
| |__   ___   ___ | |_|___ \ __| | ___   ___| | _____ _ __
| '_ \ / _ \ / _ \| __| __) / _` |/ _ \ / __| |/ / _ \ '__|
| |_) | (_) | (_) | |_ / __/ (_| | (_) | (__|   <  __/ |
|_.__/ \___/ \___/ \__|_____\__,_|\___/ \___|_|\_\___|_|
Boot2Docker version 1.8.2, build master : aba6192 - Thu Sep 10 20:58:17 UTC 2015
Docker version 1.8.2, build 0a8c2e3
docker@default:~$ id
uid=1000(docker) gid=50(staff) groups=50(staff),100(docker)

docker@default:~$ uname -a
Linux default 4.0.9-boot2docker #1 SMP Thu Sep 10 20:39:20 UTC 2015 x86_64 GNU/Linux

# sudoできるか確認
docker@default:~$ sudo su
root@default:/home/docker# 
 ```

上記の通り、Dockerホストに入れました。

dockerコマンドを透過的に利用できるようにする設定や、作成されたイメージは、$HOME/.docker/machine/machines/ にあります。
(デフォルトのマシンの場合は、$HOME/.docker/machine/machines/default です）

こちらに、sshのための鍵やポート、証明書、VM起動時のオプションを指定した設定ファイル（割り当てIPや環境変数など）があります。

また、Dockerホストは boot2dockerがベースなので、DockerホストそのものからDockerサービスを調整したい場合は、/var/lib/boot2docker/ あたりを見ることになります。

## docker run hello-world してみる

前置きが長くなってしまいました...

ふたたび、Macのターミナルに戻ります。
まだimageが何も無い状態で、なにか試してみます。

```
% docker-machine status default
Running
% docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
% docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
535020c3e8ad: Pull complete 
af340544ed62: Pull complete 
Digest: sha256:a68868bfe696c00866942e8f5ca39e3e31b79c1e50feaee4ce5e28df2f051d5c
Status: Downloaded newer image for hello-world:latest

Hello from Docker.
This message shows that your installation appears to be working correctly.

--- [ 略 ] ---

% docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                      PORTS               NAMES
a792329828c0        hello-world         "/hello"            2 minutes ago       Exited (0) 41 seconds ago                       adoring_hopper
% docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
hello-world         latest              af340544ed62        8 weeks ago         960 B


```

うまくDocker Hubからイメージを取って来て、コンテナを起動、　”Hello from Docker.”のメッセージを出して終了してくれました。


### もしだんまりになっちゃったら？

プロキシ環境下では、うまくDockerホストがDocker Hubからイメージを取って来れないケースがあります。

```
% docker run helloworld
Unable to find image 'helloworld:latest' locally
# ....だんまりになってしまう

Network timed out while trying to connect to https://index.docker.io/v1/repositories/library/hello-world/images. You may want to check your internet connection or if you are behind a proxy.
```

わたしの場合は、よく分からなかったので、以下のように docker-machine でいったんVMを作りなおしました。

```
docker-machine create -d virtualbox \
    --engine-env HTTP_PROXY=プロキシのURL \
    --engine-env HTTPS_PROXY=プロキシのURL \
    --engine-env NO_PROXY=PROXY経由から除外したいドメイン \
    default
```

上記の通り、この設定は、$HOME/.docker/machine/machines/default/config.json に指定になります。

また、場合によっては、Dockerで起動したコンテナ内でもProxyを明示しないと上手くいかないかも知れません..。

## Kitematic も使ってみよう

さて、なんとか希望通りDockerの操作ができるようになりました。

Docker Toolbox をインストールすると **Kitematic** というGUIツールも一緒に入ります。(説明用の動画を見ると、発音的には、「カイトマティック」と言うようです。凧をあやつるツール、的な意味でしょうか）

こちらも起動すると何が起きるかと言うと、

- 初回の起動時、Dockerホスト用のVMが無ければ、Vagrant経由で背後でVMを作る
- 起動時には "Docker Hubにアカウント作りませんか〜？" なダイアログが出る
 - ここはSkipしても問題無し
- 起動すると、docker ps -a したのと同じく、コンテナ一覧が表示される

という感じになります。

![kitematic.png](https://qiita-image-store.s3.amazonaws.com/0/27976/3d51114a-c5bb-3a75-cbd5-68221d748e42.png "kitematic.png")



このGUIツールから、Docker Hub上のイメージを検索 + 追加したりできます。また、dockerコマンドが使えるように環境変数を設定済みのターミナルを開くこともできます。

それから、各コンテナに対しては、GUI経由で以下のことができます。

- コンテナ名の編集（指定してないと勝手に名前が付く）ので、必要があれば分かりやすいものに修正可能。
 - Ref. [Dockerコンテナのおもしろい名前](http://deeeet.com/writing/2014/07/15/docker-container-name/)
- コンテナのSAVE (コミット）が可能
- コンテナにアタッチできる（ターミナルが勝手に起動して、コンテナの中に入れる）
- pullしたDockerのドキュメントページにアクセスできる（リンク）
- 環境変数が調整できる

![kitematic-2.png](https://qiita-image-store.s3.amazonaws.com/0/27976/299f4580-f187-96a7-5396-4c2d65c4d0c9.png "kitematic-2.png")

Dockerのイメージは別として、何度も作業するとコンテナの数が非常に増えます。

その辺のゴミ掃除を忘れてしまいがちですので、わたしには助かるな〜、と思いました^^


## Docker QuickStart Terminal以外の別のターミナルからの操作

Docker Quickstart Terminal  や、Kitematic を使って自動で立ち上がったターミナルからは、dockerコマンドが透過的に使えますが、別ターミナルを開いて docker ps と打っても、そのままでは怒られておしまいです。

接続したいDockerホストのURLを環境変数に設定してからだと、docker コマンドが通るようになります:)
もしくは、docker-machine env default (Dockerホストのマシン名）を実行してから、その指示に従うと、必要な設定が入って接続できるようになります。

```
% docker ps
Get http:///var/run/docker.sock/v1.20/containers/json: dial unix /var/run/docker.sock: no such file or directory.
* Are you trying to connect to a TLS-enabled daemon without TLS?　# <- 怒られる....
  
# まずは "docker-machine env default" を実行
% docker-machine env default
export DOCKER_TLS_VERIFY="1"
export DOCKER_HOST="tcp://192.168.xxx.xxx:2376"
export DOCKER_CERT_PATH="/Users/xxx/.docker/machine/machines/default"
export DOCKER_MACHINE_NAME="default"
# Run this command to configure your shell:
# eval "$(docker-machine env default)"

# 上記の指示に従って実行
# dockerコマンドが透過的に通るようになります
% eval "$(docker-machine env default)" \
% docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
hello-world         latest              af340544ed62        9 weeks ago         960 B


# もしくは、こちらのおまじない
# Docker QuickStart Terminalの最初にこちらを実行しています

% bash -c "clear && DOCKER_HOST=tcp://xxx.xxx.xxx.xxx:2376 DOCKER_CERT_PATH=~$HOME/.docker/machine/machines/default DOCKER_TLS_VERIFY=1 /bin/bash" 
```

# まとめ

以上、長々としてしまいましたが、実際に使ってみてのメモ、感想、ハマりポイントを上げてみます。

## ハマりポイント

### プロキシ環境下

- プロキシ環境下での利用はご注意を
 - DockerホストそのもののProxy設定が必要（VM作成時やconfig.jsonで調整）
 - Dockerホスト内でのdockerプロセスについても、Proxy設定が必要
 　- boot2docker内の/var/lob/boot2docker/profileをチェック

### Macのターミナルからの操作
 
- DockerホストのVMが起動していても、通常のターミナルからはdockerコマンドは通らないので、環境変数を通すななどの作業が必要
 - docker-machine env xxxx を使って環境変数を通してから、docker コマンドを使ってみること
- うまくDockerホストが作れてないなと思ったら、一回消すのもアリ
 - docker-machine rm default (マシン名）や、VirtualBoxの管理画面から削除可能
 - 消しても、KitematicやDocker QuickStart Terminal起動時に再作成してくれる

### "no space left on device" エラー！

- 初期Dockerホストの構成だと、”no space left on device”と言われてサイズの大きいイメージをpullできないことがある
 - 本家のこちらに記載：[Getting “no space left on device” errors with Boot2Docker?](https://docs.docker.com/articles/b2d_volume_resize/)

わたしの場合は、以下の方法でDockerホストを再作成しています。

 - docker-machine create の際に、--virtualbox-disk-size "50000" を指定してサイズアップ
  - デフォルトは--virtualbox-disk-size "20000" (20GB) 

## 感想など

- Macのターミナルから『透過的』にdockerコマンドが使えるのが便利
- docker-compose についてはまだ理解やトライができませんでした...

個人的には、透過的にDockerホストに働きかける仕組みが面白いと思っていて、特にWindows版はどうやって動かすんだろうと興味が湧いております。

分かりにくい点や、間違い、認識不足などありましたら、ご指摘いただけると幸いです。

## 補足：boot2dockerはどうなったの？

最初は技術評論社のWeb+DB Pressを参考に、Mac用のDockerツールのboot2docker を入れてみたのですが、結局挫折（というか、やっぱりVagrantで十分かも...)と思っていたん中断しておりました。

boot2dockerでもDocker Toolboxでも、Mac上でネイティブにDockerのプロセス・サービスが上がる訳ではなく、

- 実際のDocker用ホストとしてはVirtualBox下でのboot2docker ~~Ubuntu~~ を利用する点

には、変更はありません。

せっかく作ったVirtualBoxの仮想マシンですし、Docker Toolboxからでも利用できるように、マイグレーションの方法が用意されています。（まだ試していません）

*(※ご指摘をいただき、Dockerホストのイメージのboot2dockerについて修正いたしました。DQNEOさま、ありがとうございました。ホストそのものに対しては、インストールやネットワーク設定など、もろもろ方法が異なってしまうので、申し訳ございませんでした)*

## 追記：20151013


ディストリビューションについての修正にあわせて、[boot2docker](http://boot2docker.io) についての確認を追記しました。
Docker Toolboxの使っているboot2dockerは、Tiny Core LinuxベースのDocker専用の軽量ディストリビューションとのことだそうです。
（VM初期割り当ては メモリ1G, 1CPUの設定で起動しています）

以下、環境の確認。

```
docker@default:~$ uname -a
Linux default 4.0.9-boot2docker #1 SMP Thu Sep 10 20:39:20 UTC 2015 x86_64 GNU/Linux

docker@default:~$ cat /etc/issue 
Core Linux

docker@default:~$ cat /etc/os-release 
NAME=Boot2Docker
VERSION=1.8.2
ID=boot2docker
ID_LIKE=tcl
VERSION_ID=1.8.2
PRETTY_NAME="Boot2Docker 1.8.2 (TCL 6.4); master : aba6192 - Thu Sep 10 20:58:17 UTC 2015"
ANSI_COLOR="1;34"
HOME_URL="http://boot2docker.io"
SUPPORT_URL="https://github.com/boot2docker/boot2docker"
BUG_REPORT_URL="https://github.com/boot2docker/boot2docker/issues"

```

また、パッケージのインストールやOSのアップグレードは良く判らなかったのですが、docker-machine コマンドでupgradeできるようでした。

ちょうど新しいリリースが出ていたので、実際に下記のとおりに試してみています。

```
# upgradeしてみます
% docker-machine upgrade default
Stopping machine to do the upgrade...
Upgrading machine default...
Downloading https://github.com/boot2docker/boot2docker/releases/download/v1.8.3/boot2docker.iso to /Users/takano/.docker/machine/cache/boot2docker.iso...
Starting machine back up...
Starting VM...

# sshで確認
% docker-machine ssh default cat /etc/os-release
NAME=Boot2Docker
VERSION=1.8.3
ID=boot2docker
ID_LIKE=tcl
VERSION_ID=1.8.3
PRETTY_NAME="Boot2Docker 1.8.3 (TCL 6.4); master : af8b089 - Mon Oct 12 18:56:54 UTC 2015"
ANSI_COLOR="1;34"
HOME_URL="http://boot2docker.io"
SUPPORT_URL="https://github.com/boot2docker/boot2docker"
BUG_REPORT_URL="https://github.com/boot2docker/boot2docker/issues"
```