Compose を始めましょう¶
このページにおいて Docker Compose 上で動く簡単な Python ウェブ アプリケーションを作り出しましょう。このアプリケーションは Flask フレームワークを使い、Redis を使ってアクセスカウンタを管理します。このサンプルでは Python を用いていますが、たとえ Python に詳しくない方でも、ここに示す概念は十分に理解できるようになっています。
必要条件¶
Docker Engine と Docker Compose がインストール済かどうか確認します。Python と Redis はインストール不要です。どちらも Docker イメージで提供されます。
ステップ1:セットアップ¶
アプリケーションの依存関係を定義します。
プロジェクト用のディレクトリを作成します。
$ mkdir composetest
$ cd composetest
プロジェクトのディレクトリ内に
app.py
という名前のファイルを作成し、以下の内容を貼り付けます。
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)
この例では、 redis
とはアプリケーションのネットワーク上にある redis コンテナのホスト名です。Redis 用のポートとしてデフォルトの 6379
を使います。
プロジェクトのディレクトリ内に別の
requirements.txt
を作成し、以下の内容を貼り付けます。
flask
redis
ステップ2:Dockerfile の作成¶
このステップでは、 Docker イメージを構築する Dockerfile を書きます。そのイメージには Python 自身を含む、 Python アプリケーションが必要とする全ての依存関係を含みます。
プロジェクトのディレクトリ内で、 Dockerfile
という名前のファイルを作成し、以下の内容を貼り付けます。
# syntax=docker/dockerfile:1
FROM python:3.7-alpine
WORKDIR /code
ENV FLASK_APP=app.py
ENV FLASK_RUN_HOST=0.0.0.0
RUN apk add --no-cache gcc musl-dev linux-headers
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt
EXPOSE 5000
COPY . .
CMD ["flask", "run"]
これは Docker に対して指示を伝えます。
Python 3.7 イメージでイメージの構築を開始
作業ディレクトリ を/code
に指定flask
コマンドが使う環境変数を指定gcc と他の依存関係をインストール
requirements.txt
をコピーし、Python 依存関係をインストールコンテナがポート 5000 をリッスンするよう、イメージに対してメタデータの記述を追加
プロジェクト内にある現在のディレクトリ
.
を、イメージ内の作業ディレクトリ .
にコピーコンテナ実行時のデフォルト コマンド
flask run
を指定
Dockerfile の書き方についての詳細は、 Docker ユーザガイド と Dockerfile リファレンス をご覧ください。
ステップ3:Compose ファイル内でサービスを定義¶
プロジェクトのディレクトリに移動し、 docker-compose.yml
という名前のファイルを作成し、以下の内容を貼り付けます。
version: "3.9"
services:
web:
build: .
ports:
- "8000:5000"
redis:
image: "redis:alpine"
この Compose ファイルは web
と redis
という2つのサービスを定義します。
web サービス¶
web
サービスは、現在のディレクトリ内にある Dockerfile
から構築したイメージを使います。それから、コンテナのポートと、ホストマシン上に公開するポート 8000
を 5000
を使います。
redis サービス¶
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:8000/
を開き、アプリケーションの稼動を確認します。Linux 上で Docker をネイティブに使っている場合や、 Docker Desktop for Mac 、 Docker Desktop for Windows の場合、これでウェブアプリは Docker デーモンのホスト上でポート 8000 をリッスンします。ウェブブラウザで http://localhost:8000 を開き、
Hello World
メッセージを確認します。表示できなければ、 http://127.0.0.1:8000 で試します。ブラウザに次のような文字が表示されるでしょう。
Hello World! I have been seen 1 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 <タグ または id>
でイメージを確認できます。
アプリケーションを停止するには、2つめのターミナル内のプロジェクトディレクトリ内で
docker compose down
を実行するか、アプリを起動した元々のターミナルで CTRL+C を実行します。
ステップ5:Compose ファイルに バインド マウント を追加¶
プロジェクトのディレクトリ内にある docker-compose.yml
を編集し、 web
サービスに バインド マウント を追加します。
version: "3.9"
services:
web:
build: .
ports:
- "8000:5000"
volumes:
- .:/code
environment:
FLASK_ENV: development
redis:
image: "redis:alpine"
新しい volumes
キーは、ホスト上のプロジェクトがあるディレクトリ(現在のディレクトリ)を、コンテナ内の /code
にマウントします。これにより、イメージを再構築しなくても、実行しながらコードを変更できるようになります。 environment
キーは環境変数 FLASK_ENV
を設定します。これは flask run
に対し、開発モードでの実行と、コードに変更があれば再読込するように伝えます。このモードは開発環境下でのみ使うべきです。
ステップ6:Compose でアプリの再構築と実行¶
プロジェクトのディレクトリで、更新した 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)
Hello World
メッセージをウェブブラウザで再度確認すると、再読込で数値が増えるのが分かります。
重要
共有フォルダ、ボリューム、バインド マウント
プロジェクトが
Users
ディレクトリ(cd ~
)の外にある場合、Dockerfile とボリュームが使おうとしているドライブや場所を共有する必要があります。実行時にアプリケーションのファイルが見つからないというエラーが出た場合、ボリューム マウントが拒否されているか、サービスが起動できないため、ファイルまたはドライブの共有を試します。ボリューム マウントには、C:\Users
(Windows)や/Users
(Mac)の外でプロジェクト用の共有ドライブが必要となります。そのため、Docker Desktop for Windows 上のあらゆるプロジェクトは Linux コンテナー が必要です。詳しい情報は、 Docker for Mac の ファイル共有 と、一般的な設定については コンテナ内でのデータ管理 をご覧ください。古い Windows OS 上で Oracle VirtualBox を使っている場合、 VB trouble ticket に示されている共有フォルダに関する問題が起こるかもしれません。より新しい Windows システムであれば、 Docker for Windows の要件を満たすため、VirtualBox は必要としません。
ステップ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 docker-entrypoint.sh redis ... Up 6379/tcp
composetest_web_1 flask run Up 0.0.0.0:8000->5000/tcp
docker compose run
コマンドは、サービスに対して一度だけコマンドを実行できます。たとえば、 web
サービスに対し、環境変数が何かを見るには、次のようにします:
$ docker compose run web env
docker compose --help
で、他の利用可能なコマンドを確認できます。
docker compose up -d
で Compose を起動した場合は、サービスを
$ docker compose stop
コンテナ全体を削除し、全てを終了するには、 down
コマンドを使います。 --volumes
を追加すると、 Redis コンテナによって使われたデータ ボリュームも削除します。
$ docker compose down --volumes
これで、 Compose がどのように機能するかの基本が分かりました。
次は何を読みますか¶
次は、Compose のサンプルアプリ を試しましょう。
Compose 設定ファイル リファレンス
ボリュームやバインド マウントについて学ぶには Docker のデータ管理 をご覧ください。
参考
- Get started with Docker Compose