複数Dockerをまとめて扱えるDocker Compose

Dockerを起動するのにシェルやバッチファイルを作るのはイケてないよね、ということで、Dockeer Compose入門してみます。

公式

Docker ドキュメント日本語化プロジェクト — Docker-docs-ja 17.06.Beta ドキュメント

日本人なのでまずは日本語ドキュメントから。
英語は以下から参照出来ます。

Docker Compose | Docker Documentation

Docker Composeを端的に表しているのが以下の一文かなと。
Compose is a tool for defining and running multi-container Docker applications.

インストール

Install Docker Composeの章を読んでからインストールしようと意気込んでいましたが、
Docker for MacにDocker Composeが含まれているから何もする必要なかったことが判明。

バージョン

$ docker-compose version
docker-compose version 1.20.1, build 5d8c71b
docker-py version: 3.1.4
CPython version: 3.6.4
OpenSSL version: OpenSSL 1.0.2n  7 Dec 2017
$ docker version
Client:
 Version:   18.03.0-ce
 API version:   1.37
 Go version:    go1.9.4
 Git commit:    0520e24
 Built: Wed Mar 21 23:06:22 2018
 OS/Arch:   darwin/amd64
 Experimental:  false
 Orchestrator:  swarm

Server:
 Engine:
  Version:  18.03.0-ce
  API version:  1.37 (minimum version 1.12)
  Go version:   go1.9.4
  Git commit:   0520e24
  Built:    Wed Mar 21 23:14:32 2018
  OS/Arch:  linux/amd64
  Experimental: true

Getting Start

まずは手順に沿ってやってみます。

Get started with Docker Compose | Docker Documentation

  1. dir作成
  2. app.py作成
  3. requirements.txt作成
  4. Dockerfile作成
  5. docker-compose.yml作成
  6. ビルドと実行
$ docker-compose up
Creating network "composetest_default" with the default driver
Building web
Step 1/5 : FROM python:3.4-alpine
3.4-alpine: Pulling from library/python
ff3a5c916c92: Already exists
44014a6ad6bc: Pull complete
3919b90fd9f1: Pull complete
ceed1ab3250e: Pull complete
53eb14a7dcfc: Pull complete
Digest: sha256:c9296e2eb4cbed9e81b8a02d5fd623191c6118abd2449f8976878fffa426fcb4
Status: Downloaded newer image for python:3.4-alpine
 ---> 2b794a3b3750
Step 2/5 : ADD . /code
 ---> a54e58cb2a2a
Step 3/5 : WORKDIR /code
Removing intermediate container 486c5ca4671a
 ---> 4ec62976448a
Step 4/5 : RUN pip install -r requirements.txt
 ---> Running in a90df7cdcaf5
Collecting flask (from -r requirements.txt (line 1))
  Downloading https://files.pythonhosted.org/packages/7f/e7/08578774ed4536d3242b14dacb4696386634607af824ea997202cd0edb4b/Flask-1.0.2-py2.py3-none-any.whl (91kB)
Collecting redis (from -r requirements.txt (line 2))
  Downloading https://files.pythonhosted.org/packages/3b/f6/7a76333cf0b9251ecf49efff635015171843d9b977e4ffcf59f9c4428052/redis-2.10.6-py2.py3-none-any.whl (64kB)
Collecting click>=5.1 (from flask->-r requirements.txt (line 1))
  Downloading https://files.pythonhosted.org/packages/34/c1/8806f99713ddb993c5366c362b2f908f18269f8d792aff1abfd700775a77/click-6.7-py2.py3-none-any.whl (71kB)
Collecting Jinja2>=2.10 (from flask->-r requirements.txt (line 1))
  Downloading https://files.pythonhosted.org/packages/7f/ff/ae64bacdfc95f27a016a7bed8e8686763ba4d277a78ca76f32659220a731/Jinja2-2.10-py2.py3-none-any.whl (126kB)
Collecting Werkzeug>=0.14 (from flask->-r requirements.txt (line 1))
  Downloading https://files.pythonhosted.org/packages/20/c4/12e3e56473e52375aa29c4764e70d1b8f3efa6682bef8d0aae04fe335243/Werkzeug-0.14.1-py2.py3-none-any.whl (322kB)
Collecting itsdangerous>=0.24 (from flask->-r requirements.txt (line 1))
  Downloading https://files.pythonhosted.org/packages/dc/b4/a60bcdba945c00f6d608d8975131ab3f25b22f2bcfe1dab221165194b2d4/itsdangerous-0.24.tar.gz (46kB)
Collecting MarkupSafe>=0.23 (from Jinja2>=2.10->flask->-r requirements.txt (line 1))
  Downloading https://files.pythonhosted.org/packages/4d/de/32d741db316d8fdb7680822dd37001ef7a448255de9699ab4bfcbdf4172b/MarkupSafe-1.0.tar.gz
Building wheels for collected packages: itsdangerous, MarkupSafe
  Running setup.py bdist_wheel for itsdangerous: started
  Running setup.py bdist_wheel for itsdangerous: finished with status 'done'
  Stored in directory: /root/.cache/pip/wheels/2c/4a/61/5599631c1554768c6290b08c02c72d7317910374ca602ff1e5
  Running setup.py bdist_wheel for MarkupSafe: started
  Running setup.py bdist_wheel for MarkupSafe: finished with status 'done'
  Stored in directory: /root/.cache/pip/wheels/33/56/20/ebe49a5c612fffe1c5a632146b16596f9e64676768661e4e46
Successfully built itsdangerous MarkupSafe
Installing collected packages: click, MarkupSafe, Jinja2, Werkzeug, itsdangerous, flask, redis
Successfully installed Jinja2-2.10 MarkupSafe-1.0 Werkzeug-0.14.1 click-6.7 flask-1.0.2 itsdangerous-0.24 redis-2.10.6
Removing intermediate container a90df7cdcaf5
 ---> 1b7cc82509af
Step 5/5 : CMD ["python", "app.py"]
 ---> Running in 24fa47584686
Removing intermediate container 24fa47584686
 ---> 2c4f068e2e83
Successfully built 2c4f068e2e83
Successfully tagged composetest_web:latest
WARNING: Image for service web was built because it did not already exist. To rebuild this image you must use `docker-compose build` or `docker-compose up --build`.
Pulling redis (redis:alpine)...
alpine: Pulling from library/redis
ff3a5c916c92: Already exists
5fbab8756652: Pull complete
ff7d4663b06c: Pull complete
0b5cf71258c2: Pull complete
54bbb9bad8ba: Pull complete
8fe9a341d124: Pull complete
Digest: sha256:686ab026fae07b3b99a8e74210c361714a80311ecc55f23b349ae930ed2f5a95
Status: Downloaded newer image for redis:alpine
Creating composetest_web_1   ... done
Creating composetest_redis_1 ... done
Attaching to composetest_web_1, composetest_redis_1
redis_1  | 1:C 21 Jun 12:34:54.121 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
redis_1  | 1:C 21 Jun 12:34:54.121 # Redis version=4.0.10, bits=64, commit=00000000, modified=0, pid=1, just started
redis_1  | 1:C 21 Jun 12:34:54.121 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
redis_1  | 1:M 21 Jun 12:34:54.122 * Running mode=standalone, port=6379.
redis_1  | 1:M 21 Jun 12:34:54.122 # 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_1  | 1:M 21 Jun 12:34:54.122 # Server initialized
redis_1  | 1:M 21 Jun 12:34:54.124 # 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_1  | 1:M 21 Jun 12:34:54.124 * Ready to accept connections
web_1    |  * Serving Flask app "app" (lazy loading)
web_1    |  * Environment: production
web_1    |    WARNING: Do not use the development server in a production environment.
web_1    |    Use a production WSGI server instead.
web_1    |  * Debug mode: on
web_1    |  * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
web_1    |  * Restarting with stat
web_1    |  * Debugger is active!
web_1    |  * Debugger PIN: 231-746-569

動作確認

http://localhost:5000にアクセスします。
ブラウザにHello world! I have been seen x times.と表示されれば正常に動作しています。
xは、ページリロード、ないしはページをロードするたびに1つずつインクリメントされていきます。

アクセスカウンター的なものですかねこれ。

まとめ

Docker Composeを公式の手順に沿って試してみました。
docker-composeの意味はまだ理解していないので…、おいおい理解していきたいと思います。

本題ではないですが、pythonを書いて、それをDockerに読ませてビルド/実行という使い方もあるんだーとびっくり。
Javaでも同じことが出来そうですね。FROM javaナントカあたりを書き変えれば複数のJDKをインストールすることなくビルド/実行出来るな…。