Docker Composeを使ってIBM Containerを管理する

#はじめに

[Docker Compose](https://docs.docker.com/compose/)とは、複数のコンテナから構成されるサービスを一元管理するツールです。それぞれ役割が違う複数のコンテナをひとつのymlファイルで定義し、`docker-compose`コマンドを使ってそれらのコンテナのビルド、起動、終了、ログの確認などを行うことができます。2016年4月6日に、このDocker Composeを使ってIBMのBluemixが提供する[IBM Containerを管理することができるようになりました](http://ryanjbaxter.com/cloud/bluemix/docker/2016/04/06/bluemix-docker-compose.html)。この記事では、Docker Composeを使ったIBM Containerの管理方法について解説します。

検証環境
- Windows7
- Docker Toolbox 1.10.0
- Cloud Foundry Command Line Interface 6.18.0
- IBM Containers Plug-in 0.8.889
- Docker Compose 1.6.0

上記のソフトウェアのインストールや設定方法については、他の文献を当たってください。

#事前準備
今回の解説では、docker.comにある[こちら](https://docs.docker.com/compose/gettingstarted/)のアプリケーションをIBM Containerに展開してみます。まずは、リンク先にあるDockerfile、app.pyとrequirements.txtを作業ディレクトリにコピーします。

```text:Dockerfile
FROM python:2.7
ADD . /code
WORKDIR /code
RUN pip install -r requirements.txt
CMD python app.py
```

```py:app.py
from flask import Flask
from redis import Redis

app = Flask(__name__)
redis = Redis(host='redis', port=6379)

@app.route('/')
def hello():
    redis.incr('hits')
    return 'Hello World! I have been seen %s times.' % redis.get('hits')

if __name__ == "__main__":
    app.run(host="0.0.0.0", debug=True)
```

```text:requirements.txt
flask
redis
```

以上が準備できたら、コンテナをいったんビルドします。

```shell-session
$ docker build -t web .
Sending build context to Docker daemon  5.12 kB
Step 1 : FROM python:2.7
 ---> 11a8b7c7f0ca
Step 2 : ADD . /code
 ---> 7ae083e86c6e
...
Successfully built 47f64f2b592e
```

すると、webというコンテナのイメージがローカルに作成されます。

```shell-session
$ docker images | grep ^web
web                                                                    latest              47f64f2b592e        About a minute ago   671.9 MB
```

以上で事前準備は完了です。

# Docker Composeを使ってBluemixにコンテナを展開する
では、さっそくBluemixへコンテナを展開してみましょう。IBM Containerを利用するために、まずは`cf login`と`cf ic login`を実行します。次に、IBM Containerの初回の利用時は、namespaceの定義が必要となるため、`cf ic namespace set <NAMESPCE>`を実行します。一度namespaceを作成すると、名前の変更はできないので注意してください。

```shell-session
$ cf ic namespace set smatsui
```

これで、Bluemix上のレジストリに個人のnamespaceが作成されました。このnamespaceに、先ほど作成したwebというコンテナとredisコンテナのイメージを登録します。自分で作成したwebコンテナについては、ローカル環境にあるコンテナイメージとBluemix上のnamespaceとの関連付けを行い、Bluemixへコンテナイメージをpushする、という流れになります。


```shell-session
$ docker tag web registry.ng.bluemix.net/smatsui/web
$ docker push registry.ng.bluemix.net/smatsui/web
The push refers to a repository [registry.ng.bluemix.net/smatsui/web]
621f0324fb5f: Pushed
2198ea4f3d49: Pushed
...
```

Docker hub上で提供されるredisのコンテナイメージは、Docker hubからBluemixへコピーします。

```shell-session
$ cf ic cpi redis registry.ng.bluemix.net/smatsui/redis
Sending build context to Docker daemon 2.048 kB
Step 1 : FROM redis
 ---> 182085c5730c
...
```

Docker Composeのymlファイルを作成します。

```yaml:docker-compose-bluemix.yml
web:
  image: registry.ng.bluemix.net/smatsui/web
  ports:
   - "5000:5000"
  links:
   - redis
redis:
  image: registry.ng.bluemix.net/smatsui/redis
```

さて、いよいよdocker-composeコマンドを作って、webコンテナとredisコンテナをいっぺんに起動します！ですが、その前に、`cf ic login`コマンドをもう一度実行して、標準出力に現れるオプション2の設定（環境変数DOCKER_HOSTやDOCKER_CERT_PATHの設定）を済ませておきます。ではdocker-composeコマンドを実行してみましょう。

```shell-session
$ docker-compose -f docker-compose-bluemix.yml up -d
Creating dockercompose_redis_1
Creating dockercompose_web_1
$ docker ps
CONTAINER ID        IMAGE                                          COMMAND             CREATED             STATUS                  PORTS               NAMES
644eebc1-85e        registry.ng.bluemix.net/smatsui/web:latest     ""                  37 minutes ago      Running 7 seconds ago   5000/tcp            dockercompose_web_1
ce869200-b3e        registry.ng.bluemix.net/smatsui/redis:latest   ""                  38 minutes ago      Running 9 seconds ago                       dockercompose_redis_1
```

コマンドラインから、二つのコンテナがいっぺんに立ち上がったことが確認できました。Bluemixのダッシュボードのほうを確認してみましょう。
![bluemix_dashboard.png](https://qiita-image-store.s3.amazonaws.com/0/16430/d49795ab-8aa7-f3e2-252b-901dff466bc6.png)

二つのコンテナがRunningの状態になっています。ここで起動したサービスにブラウザからアクセスするためには、IPアドレスを取得してwebコンテナに割り当てる必要があります。まずはIPアドレスを取得します。

```shell-session
$ cf ic ip request
OK
The IP address "169.44.113.146" was obtained.
```

取得したIPアドレスをwebコンテナに割り当てます。

```shell-session
$ cf ic ip bind 169.44.113.146 dockercompose_web_1
OK
The IP address was bound successfully.
```

さて、果たして起動したサービスにブラウザからアクセスすることはできるのでしょうか？ブラウザにIPアドレスとポート番号を打ち込んでみると。。。
![browser_1.png](https://qiita-image-store.s3.amazonaws.com/0/16430/9c962646-f5f2-7761-e5e3-c618c34e10be.png)
やったー！Bluemix上でサービスが動いているようです！ブラウザ上でF5を連打して、番号がincrementされることも確認できました。
![browser_5.png](https://qiita-image-store.s3.amazonaws.com/0/16430/92bc6b5c-8214-0203-d5c7-683739754275.png)

#Docker Composeを使ってコンテナの停止と削除を行う
先ほど取得したIPアドレスは、誰でも自由にアクセスできるアドレスです。サンプルアプリを誰でもアクセスできる環境に放置するのは気持ち悪いので、最後にコンテナを停止して削除します。

```shell-session
$ docker-compose stop
Stopping dockercompose_web_1 ...
Stopping dockercompose_redis_1 ...
Stopping dockercompose_redis_1 ... done
$ docker-compose rm
Going to remove dockercompose_web_1, dockercompose_redis_1
Are you sure? [yN] y
Removing dockercompose_web_1 ...
Removing dockercompose_redis_1 ...
Removing dockercompose_redis_1 ... done
```

以上で、Bluemix上のコンテナの削除が完了しました。

#終わりに

今回は非常に簡単なサンプルアプリを取り上げて、Docker Composeを使ってIBM Containerの作成、起動、停止、削除を試してみました。しかし、せっかくクラウド上にコンテナを展開するのであれば、Docker Composeが提供するscale機能も試してみたいところです。というわけで、次回はdocker-compose scaleコマンドを実行してIBM Containerの数が増減するか、確認してみようと思います。