Docker MachineでDigital OceanにDocker環境を構築する

Docker Machineを使ってDigital OceanにDocker環境を構築・コンテナを起動までを行ってみます。

# Docker Machineとは

Docker Machineはコマンド1つでDockerデーモンがインストールされた環境を構築するためのツールです。主要なクラウドサービスの多くで既に使えるようになっています。

2015/3/1現在下記プロバイダーに対応しています。

* Amazon EC2
* Microsoft Azure
* Microsoft Hyper-V
* DigitalOcean
* Google Compute Engine
* OpenStack
* Rackspace
* SoftLayer
* VirtualBox
* VMware Fusion
* VMware vCloud Air
* VMware vSphere

また、現在下記プロバイダの対応についてPull Requestがオープンしており開発が進められています。

https://github.com/docker/machine/pulls?q=is%3Aopen+is%3Apr+label%3Aproposed-driver

* vultr
* CenturyLink
* Parallels Desktop for Mac
* CloudStack
* Gandi
* Linode
* qcloud
* exoscale
* Concerto

# インストール

Docker Machineのレポジトリ(https://docs.docker.com/machine/ ) からバイナリをダウンロードし、実行権限を付けてパスの通っているところに配置します。

MacOSXの場合は以下のようになります。

```bash
$ curl -LO https://github.com/docker/machine/releases/download/v0.1.0/docker-machine_darwin-amd64
$ mv docker-machine_darwin-amd64 /usr/local/bin/docker-machine
$ chmod +x /usr/local/bin/docker-machine
```

インストールに成功していれば```docker-machine``` コマンドを実行するとヘルプが表示されます。

```bash
$ docker-machine
```

# Digital Oceanのアクセストークンを取得する

machineからDigital Oceanを操作するためにアクセストークンを取得しておきます。

1. Digitial Oceanの管理画面にログインし、左側にある「App & API」をクリック
2. 「Generate new token」をクリック
3. 「Token Name」にトークンの名前を入力し、「Write」にチェックを入れて「Generate Token」をクリック

取得したアクセストークンを環境変数として扱えるよう以下のコマンドを実行します。

```bash
$ export DIGITALOCEAN_ACCESS_TOKEN=<YOUR_ACCESS_TOKEN>
```

# マシンの作成

```docker-machine create```コマンドを実行するとDocker環境が構築されます。```-d``` オプションでdigitaloceanに環境を構築することを示し、```---digitalocean-access-tonen```にアクセストークンを指定します。また環境に名前を付ける必要があります（```test```としました）。

```bash
$ docker-machine create -d digitalocean --digitalocean-access-token=$DIGITALOCEAN_ACCESS_TOKEN test
INFO[0000] Creating SSH key...                          
INFO[0002] Creating Digital Ocean droplet...            
INFO[0007] Waiting for SSH...                           
INFO[0076] Configuring Machine...                       
INFO[0160] "test" has been created and is now the active machine. 
INFO[0160] To point your Docker client at it, run this in your shell: $(docker-machine env test) 
```

ここでDigital Oceanの管理画面をみるとDropletが作成されていることが確認できます。

今回は指定しませんでしたが、Digital Oceanでは以下のオプションも指定可能です。
使用可能なオプションは```docker-machine create -h``` コマンドで確認可能です。

```bash
  --digitalocean-image="docker"       Digital Ocean image
  --digitalocean-region="nyc3"        Digital Ocean region
  --digitalocean-size="512mb"         Digital Ocean size
```

# 作成されたマシンの確認

```docker-machine ls``` コマンドで作成されたマシンを確認することができます。

```
$ docker-machine ls
NAME   ACTIVE   DRIVER         STATE     URL                          SWARM
test   *        digitalocean   Running   tcp://XXX.XXX.XXX.XXX:2376   
```

## 複数のマシンが存在する場合

Docker Machineでは複数のマシンを作成・管理することが可能です。複数のマシンが存在する場合には```docker-machine ls``` の結果は以下のようになります。

ほとんどのコマンドでは引数を省略するとACTIVEに```*``` がついているマシンが使用されます。

```bash
$ docker-machine ls
NAME     ACTIVE   DRIVER         STATE     URL                          SWARM
test01            digitalocean   Running   tcp://XXX.XXX.XXX.XXX:2376   
test02   *        digitalocean   Running   tcp://YYY.YYY.YYY.YYY:2376 
```

アクティブなマシンは```docker-machine active``` コマンドで切り替えることができます。

```bash
$ docker-machine active test01
$ docker-machine ls
NAME     ACTIVE   DRIVER         STATE     URL                          SWARM
test01   *        digitalocean   Running   tcp://XXX.XXX.XXX.XXX:2376   
test02            digitalocean   Running   tcp://YYY.YYY.YYY.YYY:2376
```

今回の例では```test``` をアクティブにしておきます。

# 作成したマシンにSSH

```docker-machine ssh```コマンドで作成したDropletへのSSHログイン、コマンド実行が可能です。

マシン名を省略した場合にはアクティブなマシンにログインします。
コマンドを実行する際にはマシン名を省略する事はできません。

```bash
$ docker-machine ssh
$ docker-machine ssh test service docker status
docker start/running, process 3202
```

# 環境変数の設定

作成した環境をローカルから使用するために環境変数を設定します。
環境変数の設定は```docker-machine env``` コマンドの結果を評価することで行う事ができます。

```bash
$ docker-machine env
export DOCKER_TLS_VERIFY=yes
export DOCKER_CERT_PATH=/YOUR_HOME/.docker/machine/machines/test
export DOCKER_HOST=tcp://XXX.XXX.XXX.XXX:2376
$ $( docker-machine env )
```

# マシン上でコンテナを起動

## hello world

環境変数を設定した状態で```docker run``` コマンドを実行すると、作成したマシン上でコンテナを起動することができます。

デフォルトではTLSを利用して安全な通信を行うため```docker-machine config``` コマンドによって得られるオプションを付けます。

```bash
$ docker-machine config
--tls --tlscacert=/YOUR_HOME/.docker/machine/machines/test/ca.pem --tlscert=/YOUR_HOME/.docker/machine/machines/test/cert.pem --tlskey=/YOUR_HOME/.docker/machine/machines/test/key.pem -H="tcp://XXX.XXX.XXX.XXX:2376"
```

```bash
$ docker $(docker-machine config) run busybox echo hello world
hello world
```

## nginx

上記の例だとリモートの環境で実行されている実感がわきにくいのでnginxのコンテナを起動してみます。

まず、次のコマンドでコンテナを起動します。

```bash
$ docker $(docker-machine config) run -d -p 80:80 dockerfile/nginx
```

次に```docker-machine ip``` コマンドでIPを確認します。

```bash
$ docker-machine ip
```

表示されたIPをブラウザで開くとnginxの画面が表示されていることが確認できます。

# マシンの削除

不要になったマシンは```docker-machine rm``` コマンドで削除することができます。

**Docker Machineは作成したマシンの情報を```~/.docker/machine``` 下
に保持しているので、```docker-machine rm``` コマンドを使わずにDropletを削除するとゴミが残り新規にマシンを作成する際などにエラーが発生する事があります。**

```bash
$ docker-machine rm test
```

# まとめ

Docker Machineを利用するとDocker環境の作成・削除を非常に簡単に行う事ができます。
VagrantなどでもDocker環境の構築自体は簡単に行えますが、Dockerの使用に特化しているので環境変数の設定などはDocker Machineを使用した方が簡単だと思います。

# 参考

* [Announcing Docker Machine Beta | Docker Blog](https://blog.docker.com/2015/02/announcing-docker-machine-beta/)
* [Docker Machine - Docker Documentation](https://docs.docker.com/machine/)