diff --git a/README.md b/README.md index e14fdcb..58ba0c4 100644 --- a/README.md +++ b/README.md @@ -165,3 +165,57 @@ $ docker push ${DOCKER_HUB_ACCOUNT}/docker-hands-on-nginx 自分の Docker Hub を確認すると,以下のように正常にイメージが公開できています. ![](images/docker_hub.png) + +## Docker Compose で複数コンテナを実行する + +Docker Compose を使うと,複数コンテナを実行することができます.Docker Compose の設定ファイルは `dockerfiles/composetest/docker-compose.yml` です.以下のような構成になり,`services` 直下を見ると `web` コンテナと `redis` コンテナを実行していることがわかります. + +```yaml +version: '3' +services: + web: + build: . + ports: + - "5000:5000" + redis: + image: "redis:alpine" +``` + +さっそく実行してみましょう.Docker Composer では `docker-compose up` コマンドを実行します. + +```sh +$ docker-compose -f dockerfiles/composetest/docker-compose.yml up -d +Starting composetest_redis_1 ... done +Starting composetest_web_1 ... done +``` + +そして `http://0.0.0.0:5000/` に接続してみましょう.ブラウザをリロードすると,アクセス回数をカウントするアプリケーションを簡単に実行することができました. + +![](images/composetest.png) + +アクセス回数のデータはどこに保存されているのでしょう?実行中の `redis` コンテナに接続してみましょう. + +まず `docker ps` コマンドで実行中のコンテナ一覧を確認します(`CONTAINER ID` は異なります).次に `docker exec` コマンドで `redis` コンテナに接続をします.コンテナ内部で Redis に接続し,保存されている `hits` キーの値を確認することができます.このように `docker exec` コマンドを使うとコンテナに接続することができます. + +```sh +$ docker ps +CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES +1fc29424e6d0 composetest_web "python app.py" 14 minutes ago Up 14 minutes 0.0.0.0:5000->5000/tcp composetest_web_1 +f20f5ec95f34 redis:alpine "docker-entrypoint.s…" 14 minutes ago Up 14 minutes 6379/tcp composetest_redis_1 + +$ docker exec -it f20f5ec95f34 /bin/sh + +/data # redis-cli + +127.0.0.1:6379> GET hits +"10" +127.0.0.1:6379> quit +``` + +動作確認後は Docker Composer を停止しておきましょう. + +```sh +$ docker-compose -f dockerfiles/composetest/docker-compose.yml stop +Stopping composetest_web_1 ... done +Stopping composetest_redis_1 ... done +``` diff --git a/dockerfiles/composetest/Dockerfile b/dockerfiles/composetest/Dockerfile new file mode 100644 index 0000000..8e67d74 --- /dev/null +++ b/dockerfiles/composetest/Dockerfile @@ -0,0 +1,5 @@ +FROM python:3.4-alpine +ADD . /code +WORKDIR /code +RUN pip install -r requirements.txt +CMD ["python", "app.py"] diff --git a/dockerfiles/composetest/app.py b/dockerfiles/composetest/app.py new file mode 100644 index 0000000..92b243b --- /dev/null +++ b/dockerfiles/composetest/app.py @@ -0,0 +1,29 @@ +import time + +import redis +from flask import Flask + + +app = Flask(__name__) +cache = redis.Redis(host='redis', port=6379) + + +def get_hit_count(): + retries = 5 + while True: + try: + return cache.incr('hits') + except redis.exceptions.ConnectionError as exc: + if retries == 0: + raise exc + retries -= 1 + time.sleep(0.5) + + +@app.route('/') +def hello(): + count = get_hit_count() + return 'Hello World! I have been seen {} times.\n'.format(count) + +if __name__ == "__main__": + app.run(host="0.0.0.0", debug=True) diff --git a/dockerfiles/composetest/docker-compose.yml b/dockerfiles/composetest/docker-compose.yml new file mode 100644 index 0000000..899cf44 --- /dev/null +++ b/dockerfiles/composetest/docker-compose.yml @@ -0,0 +1,8 @@ +version: '3' +services: + web: + build: . + ports: + - "5000:5000" + redis: + image: "redis:alpine" diff --git a/dockerfiles/composetest/requirements.txt b/dockerfiles/composetest/requirements.txt new file mode 100644 index 0000000..1a5dc97 --- /dev/null +++ b/dockerfiles/composetest/requirements.txt @@ -0,0 +1,2 @@ +flask +redis diff --git a/images/composetest.png b/images/composetest.png new file mode 100644 index 0000000..a56e3dd Binary files /dev/null and b/images/composetest.png differ