Docker Compose を試す


[Docker Advent Calendar 18日目](http://qiita.com/advent-calendar/2014/docker)の記事です。

12/4 に、Docker から Machine, Swarm, Compose という3つの機能が発表されました。(引用）

ANNOUNCING DOCKER MACHINE, SWARM, AND COMPOSE FOR ORCHESTRATING DISTRIBUTED APPS
http://blog.docker.com/2014/12/announcing-docker-machine-swarm-and-compose-for-orchestrating-distributed-apps/

[Docker Advent Calendar 17日目](http://qiita.com/advent-calendar/2014/docker)が Machine, Swarm の記事でしたので、今回は Compose を試してみようと思います。 

# Composeとは
Figからインスパイアされたプロジェクトのようです。
同時に発表された Machine, Swarm, Compose の立ち位置は以下のような感じ。

- Machine: どんな環境でもDockerの環境を構築
- Swarm: Dockerコンテナのクラスタリング
- Compose: Swarmで作ったクラスタリング環境にそれぞれのコンテナを撒く

これらのツールがそろえば Docker のオーケストレーションが可能となるということですね。

でも現状はまだまだ開発中で、Compose は [こちらの Github Issues](https://github.com/docker/docker/issues/9459) でやりとりされています。

# Composeを試す手順

[Github Issues](https://github.com/docker/docker/issues/9459) に書かれている通りにやってみます。

今回試す Compose のコマンド自体は Docker client の一部になっています。

はじめに、boot2docker のVM内 Docker と 手元の Docker client のバージョンを `1.3.2-dev` にします。
まずは VM内から。

```terminal
$ boot2docker ssh
docker@boot2docker:~$ sudo -i
root@boot2docker:~# curl -LO http://cl.ly/0Q3G1l2t301S/download/docker-1.3.2-dev-linux
root@boot2docker:~# /etc/init.d/docker stop
root@boot2docker:~# mv /usr/local/bin/docker ./docker-stable
root@boot2docker:~# mv ./docker-1.3.2-dev-linux /usr/local/bin/docker
root@boot2docker:~# chmod +x /usr/local/bin/docker
root@boot2docker:~# /etc/init.d/docker start
root@boot2docker:~# docker version
docker@boot2docker:~$ docker version
Client version: 1.3.2-dev
Client API version: 1.16
Go version (client): go1.3.3
Git commit (client): c6bf574
OS/Arch (client): linux/amd64
Server version: 1.3.2-dev
Server API version: 1.16
Go version (server): go1.3.3
Git commit (server): c6bf574
root@boot2docker:~# exit
docker@boot2docker:~$ exit
```

次に手元の Docker client を。

```terminal
$ curl -LO http://cl.ly/1J1G323h3d3T/download/docker-1.3.2-dev-darwin-amd64
$ mv /usr/local/bin/docker ./docker-stable
$ mv ./docker-1.3.2-dev-darwin-amd64 /usr/local/bin/docker
$ chmod +x /usr/local/bin/docker
$ docker version
Client version: 1.3.2-dev
Client API version: 1.16
Go version (client): go1.3.3
Git commit (client): c6bf574
OS/Arch (client): darwin/amd64
Server version: 1.3.2-dev
Server API version: 1.16
Go version (server): go1.3.3
Git commit (server): c6bf574
```

これで準備完了。
Redisを使ったアクセスカウンター付きのサイトを構築します。

Compose では、 `group.yml` に構成を記述していきます。

```group.yml
name: counter

containers:
  web:
    build: .
    command: python app.py
    ports:
      - "5000:5000"
    volumes:
      - .:/code
    links:
      - redis
    environment:
      - PYTHONUNBUFFERED=1
  redis:
    image: redis:latest
    command: redis-server --appendonly yes
```

`web` で定義しているWebサーバのコードを記述していきます。

```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)
```

```requirements.txt
flask
redis
```

そして Webサーバの Dockerfile を。

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

準備は完了！ `docker up` で起動！

```terminal
$ docker up
Recreating redis
Starting redis
Recreating web
Starting web
redis |                 _._                                                  
redis |            _.-``__ ''-._                                             
redis |       _.-``    `.  `_.  ''-._           Redis 2.8.18 (00000000/0) 64 bit
redis |   .-`` .-```.  ```\/    _.,_ ''-._                                   
redis |  (    '      ,       .-`  | `,    )     Running in stand alone mode
redis |  |`-._`-...-` __...-.``-._|'` _.-'|     Port: 6379
redis |  |    `-._   `._    /     _.-'    |     PID: 8
redis |   `-._    `-._  `-./  _.-'    _.-'                                   
redis |  |`-._`-._    `-.__.-'    _.-'_.-'|                                  
redis |  |    `-._`-._        _.-'_.-'    |           http://redis.io        
redis |   `-._    `-._`-.__.-'_.-'    _.-'                                   
redis |  |`-._`-._    `-.__.-'    _.-'_.-'|                                  
redis |  |    `-._`-._        _.-'_.-'    |                                  
redis |   `-._    `-._`-.__.-'_.-'    _.-'                                   
redis |       `-._    `-.__.-'    _.-'                                       
redis |           `-._        _.-'                                           
redis |               `-.__.-'                                               
redis | 
redis | [8] 18 Dec 08:19:20.335 # Server started, Redis version 2.8.18
redis | [8] 18 Dec 08:19:20.336 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
redis | [8] 18 Dec 08:19:20.336 # WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled.
redis | [8] 18 Dec 08:19:20.336 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
redis | [8] 18 Dec 08:19:20.336 * The server is now ready to accept connections on port 6379
web   |  * Running on http://0.0.0.0:5000/
web   |  * Restarting with reloader
```

ブラウザで `http://(boot2dockerVMのIP):5000` を開くと

```terminal
$ open http://$(boot2docker ip):5000
```

![docker_compose.png](https://qiita-image-store.s3.amazonaws.com/0/33935/35d5fbe0-cd2b-9fce-fcb4-9ec30ea88802.png "docker_compose.png")

リロードするとカウントがアップされていきます。
Docker のログを見てみると、ちゃんとアクセスログが出ています。

```terminal
web   | 192.168.59.3 - - [18/Dec/2014 08:19:36] "GET / HTTP/1.1" 200 -
```

# つまり
現状は Fig と同じ感じ。
Multi-Hosts とかも簡単になったらいいな〜。