Compose を始めましょう¶
このページにおいて Docker Compose 上で動く簡単な Python ウェブ・アプリケーションを作り出していきましょう。このアプリケーションは Flask フレームワークを使うもので、Redis を使ってアクセスカウンタを管理します。このサンプルでは Python を用いていますが、たとえ Python に詳しくない方でも、ここに示す考え方は十分に理解できるようになっています。
必要条件¶
Docker Engine と Docker Compose がインストール済であること。Python と Redis はインストールしておく必要はなく、いずれも Docker イメージによって提供されます。
ステップ1:セットアップ¶
アプリケーションの依存関係を定義します。
- プロジェクト用のディレクトリを作成します。
$ mkdir composetest
$ cd composetest
- プロジェクト用のディレクトリに移動し、好みのエディタで
app.py
という名称のファイルを作成します。
from flask import Flask
from redis import Redis
app = Flask(__name__)
redis = Redis(host='redis', port=6379)
@app.route('/')
def hello():
count = redis.incr('hits')
return 'Hello World! I have been seen {} times.\n'.format(count)
if __name__ == "__main__":
app.run(host="0.0.0.0", debug=True)
この例において redis
とはアプリケーションネットワーク上にある redis コンテナのホスト名です。Redis のポートとしてデフォルトの 6379
を利用します。
- プロジェクト用のディレクトリで、もう一つ
requirements.txt
という名称のファイルを作成し、次のようにします。
flask
redis
ステップ2:Dockerfile の作成¶
このステップでは、Docker イメージを構築する Dockerfile を作ります。そのイメージには依存するすべてもの、つまり Python と Python アプリケーションが含まれます。
プロジェクト用のディレクトリ内で、Dockerfile
という名称のファイルを作成し、次の内容にします。
FROM python:3.4-alpine
ADD . /code
WORKDIR /code
RUN pip install -r requirements.txt
CMD ["python", "app.py"]
これは Docker に対して以下の指示を行います。
- Python 3.4 イメージを使って、イメージを構築する
- カレントディレクトリ
.
を、イメージ内のパス/code
に加える - 作業用ディレクトリを
/code
に指定する - Python の依存パッケージをインストールする
- コンテナに対するデフォルトのコマンドを
python app.py
にする
Dockerfile の書き方の詳細については、 Docker ユーザ・ガイド や Dockerfile リファレンス をご覧ください。
ステップ3:Compose ファイル内でのサービス定義¶
プロジェクト用のディレクトリに移動し、docker-compose.yml
という名称のファイルを作成し、次の内容にします。
version: '3'
services:
web:
build: .
ports:
- "5000:5000"
redis:
image: "redis:alpine"
この Compose ファイルは web
と redis
という2つのサービスを定義します。web
サービスは次のように設定します。
- カレントディレクトリにある
Dockerfile
から構築されるイメージを利用します。 - コンテナの公開用ポート 5000 を、ホストマシンのポート 5000 にポートフォワードします。Flask ウェブ・サーバに対するデフォルトポート
5000
をそのまま使います。
redis
サービスは、Docker Hub レジストリから取得した Redis イメージを利用します。
ステップ4:Compose によるアプリケーションの構築と実行¶
- プロジェクト用のディレクトリで
docker-compose up
を実行しアプリケーションを起動します。
$ docker-compose up
Creating network "composetest_default" with the default driver
Creating composetest_web_1 ...
Creating composetest_redis_1 ...
Creating composetest_web_1
Creating composetest_redis_1 ... done
Attaching to composetest_web_1, composetest_redis_1
web_1 | * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
redis_1 | 1:C 17 Aug 22:11:10.480 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
redis_1 | 1:C 17 Aug 22:11:10.480 # Redis version=4.0.1, bits=64, commit=00000000, modified=0, pid=1, just started
redis_1 | 1:C 17 Aug 22:11:10.480 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
web_1 | * Restarting with stat
redis_1 | 1:M 17 Aug 22:11:10.483 * Running mode=standalone, port=6379.
redis_1 | 1:M 17 Aug 22:11:10.483 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
web_1 | * Debugger is active!
redis_1 | 1:M 17 Aug 22:11:10.483 # Server initialized
redis_1 | 1:M 17 Aug 22:11:10.483 # 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.
web_1 | * Debugger PIN: 330-787-903
redis_1 | 1:M 17 Aug 22:11:10.483 * Ready to accept connections
Compose は Redis イメージを取得し、コードに基づいたイメージを構築します。そして定義したサービスを開始します。この例では、イメージの構築時にコードが静的にコピーされます。
- ブラウザで
http://0.0.0.0:5000/
を開き、アプリケーションが動いていることを確認します。
Linux、Docker for Mac、Docker for Windows において Docker を直接使っている場合は、ウェブアプリは Docker デーモンが動くホスト上のポート 5000 をリッスンして受けつけます。ブラウザから http://localhost:5000
を入力すると、Hello World
メッセージが表示されるはずです。表示されない場合は http://0.0.0.0:5000
を試してください。
Mac や Windows 上で Docker Machine を使っている場合は、 docker-machine ip 仮想マシン名
を実行すると、Docker ホストの IP アドレスを取得できます。そこでブラウザから http://仮想マシンのIP:5000
を開きます。
ブラウザには以下のメッセージが表示されます。
Hello World! I have been seen 1 times.
- このページを再読み込みします。
数字が増えます。
Hello World! I have been seen 2 times.
- 別のターミナルウィンドウを開いて、
docker image ls
と入力し、ローカルイメージの一覧を表示してみます。
この時点におけるイメージの一覧は redis
と web
になります。
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
composetest_web latest e2c21aa48cc1 4 minutes ago 93.8MB
python 3.4-alpine 84e6077c7ab6 7 days ago 82.5MB
redis alpine 9d8fa9aa0e5b 3 weeks ago 27.5MB
docker inspect <tag または id>
によってイメージを確認することもできます。
- アプリケーションを停止させます。2つめに開いたターミナルウィンドウ上のプロジェクトディレクトリにおいて
docker-compose down
を実行します。別のやり方として、アプリを開始したはじめのターミナルウィンドウ上において CTRL+C を入力します。
ステップ5:Compose ファイルにバインドマウントを追加¶
プロジェクトディレクトリ内にある docker-compose.yml
を編集して、web
サービスへの バインドマウント を追加します。
version: '3'
services:
web:
build: .
ports:
- "5000:5000"
volumes:
- .:/code
redis:
image: "redis:alpine"
新しい volumes
というキーは、ホスト上のプロジェクトディレクトリ(カレントディレクトリ)を、コンテナ内にある /code
ディレクトリにマウントします。こうすることで、イメージを再構築することなく、実行中のコードを修正できるようになります。
ステップ6:Compose によるアプリの再構築と実行¶
プロジェクトディレクトリにて docker-compose up
を入力する際に、Compose ファイルが更新されていると、アプリは再構築され実行されます。
$ docker-compose up
Creating network "composetest_default" with the default driver
Creating composetest_web_1 ...
Creating composetest_redis_1 ...
Creating composetest_web_1
Creating composetest_redis_1 ... done
Attaching to composetest_web_1, composetest_redis_1
web_1 | * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
...
Hello World
メッセージをもう一度確認してみます。再読み込みをすると、さらにカウンタが増えているはずです。
重要
- 共有フォルダ、ボリューム、バインドマウント
- プロジェクトを Users ディレクトリ(
cd ~
)以外に置いている場合、利用している Dockerfile やボリュームのドライブやディレクトリは、共有できるようにしておく必要があります。実行時に、アプリケーションファイルが見つからない、ボリュームマウントが拒否される、サービスが起動できない、といったランタイムエラーが発生した場合は、ファイルやドライブを共有にすることを試してください。C:\Users
(Windows の場合) または/Users
(Mac の場合) 以外のディレクトリにあるプロジェクトに対して、ボリュームマウントは共有するドライブにある必要があります。これはまた、Linux コンテナ を利用する Dock for Windows におけるプロジェクトも同様のことが必要です。詳しくは Dock for Windows における 共有ドライブ や Docker for Mac における ファイル共有 を参照してください。また一般的な利用例に関しては コンテナでデータ管理 を参照してください。 - 比較的古い Windows OS 上において Oracle VirtualBox を利用している場合は、VB trouble ticket に示されている共有フォルダに関する問題が起こるかもしれません。より新しい Windows システムであれば、Docker for Windows の要件を満たすため、VirtualBox は必要としません。
- プロジェクトを Users ディレクトリ(
ステップ7:アプリケーションの更新¶
アプリケーションのコードは、ボリュームを利用してコンテナ内にマウントされましたから、コードへ変更を行うこと、それを確認することはすぐにできるようになりました。イメージを再構築することは必要ありません。
app.py
内のメッセージを変更して保存します。例えばHello World!
メッセージをHello from Docker!
に変更することにします。
return 'Hello from Docker! I have been seen {} times.\n'.format(count)
- ブラウザにてアプリを再読み込みします。メッセージは更新され、カウンタも増加しているはずです。
ステップ8:その他のコマンドを試す¶
サービスをバックグラウンドで実行したい場合は、docker-compose up
に -d
フラグ("デタッチ"モード用のフラグ)を付けます。docker-compose ps
を実行して、現在動いているものを確認します。
$ docker-compose up -d
Starting composetest_redis_1...
Starting composetest_web_1...
$ docker-compose ps
Name Command State Ports
-------------------------------------------------------------------
composetest_redis_1 /usr/local/bin/run Up
composetest_web_1 /bin/sh -c python app.py Up 5000->5000/tcp
docker-compose run
コマンドを使えば、サービスに対してのコマンド実行を行うことができます。たとえば、web
サービス上でどのような環境変数が利用可能であるかは、以下のコマンドを実行します。
$ docker-compose run web env
docker-compose --help
を実行すれば、その他のコマンドを確認できます。bash や zsh シェルにおいて コマンド補完 をインストールしている場合は、利用可能なコマンドを確認することもできます。
your services once you've finished with them:
docker-compose up -d
により Compose を起動し、サービスを停止させたい場合には、以下のコマンドを実行します。
$ docker-compose stop
コンテナも完全に削除し、すべてを終わらせる場合には down
コマンドを使います。--volumes
を指定すれば、Redis コンテナにおいて利用されているデータボリュームも削除することができます。
ここまで Compose の基本動作について見てきました。
次は何を読みますか¶
- 次は、Django 、 Rails 、 WordPress 向けのクイックスタートガイドを試しましょう。
- Compose コマンドライン・リファレンス
- Compose ファイル・リファレンス
- ボリュームやバインドマウントについての詳細は :doc:Manage data in Docker</engine/admin/volumes/index>` を参照してください。
参考
- Getting Started
- https://docs.docker.com/compose/gettingstarted/