Composeとは、複数のコンテナを定義し実行する Dockerアプリケーションのためのツールです。ComposeはYAMLファイルを使い、アプリケーションのサービスを設定します。
本演習では、Composeを使って、3つのサービスから構成されるウェブアプリケーションを定義するcompose.yamlファイルを作成し、実行します。対象レベルとしては、Docker Composeについて少し学んだことのある人向けです。本演習を通してComposeの理解を深めていただければと思います。
本記事では、Docker compose v2の使用を想定して記述しています。Docker compose v2では、Docker CLIのコマンドとしてdocker composeを使用できます。Docker-compose v1をお使いの方は、docker-composeコマンドを使用してください。互換性があるので問題なく実行できます。※Announcing Compose V2 General Availability
準備
- Dockerのセットアップ(Docker 概要とセットアップ)
- レポジトリ(https://github.com/docker/awesome-compose)のクローン
nginx-flask-mysqlディレクトリを使用します。 - Buildkitの有効化
今回使用するレポジトリには、heredocs構文を使用したDockerfileが含まれます。そのため、Buildkitを有効にする必要があります。最近のバージョンではデフォルトで有効になっています。 - 既にディレクトリ内にcompose.yamlファイルが存在するので、削除するか、名前変更をしてください。
アプリケーションの概要
今回使用するウェブアプリケーション(nginx-flask-mysql)の概要を簡単に紹介します。
pythonを使用して(backend/hello.py)、MySQLに接続し、テーブルを作成します。そのテーブルに保存した内容をFlaskウェブフレームワークを使用してポート8000で公開、そして、リバースプロキシサーバーとしてnginxを使用して、ポート80番で公開します。

本演習では、Composeファイルに以下3つのサービスを定義します。
db: MySQLデータベースbackend:pythonスクリプトproxy: nginxリバースプロキシサーバー
nginx-flask-mysqlディレクトリの構成としては次のようになっています。
|
1 2 3 4 5 6 7 8 9 10 11 |
├── backend │ ├── Dockerfile │ ├── hello.py │ └── requirements.txt ├── compose.yaml ├── db │ └── password.txt ├── proxy │ ├── conf │ └── Dockerfile └── README.md |
Composeファイルの作成
以下に示すcompose.yamlを基に、下記要件を満たすようにComposeファイルを作成してください。進め方を参考にしてください。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
services: db: image: backend: build: proxy: build: volumes: db-data: secrets: db-password: networks: backnet: frontnet: |
要件
Composeファイル内に定義すべきアプリケーションの要件を以下に示します。
dbサービスのDockerイメージはmysql:8を使用dbサービスにおけるMySQLのrootユーザーのパスワードはdb/password.txtファイルを使用dbサービスにおけるMySQLのAuthentication Pluginは、mysql_native_passwordを使用
commandを以下のよう定義してください。
|
1 |
command: '--default-authentication-plugin=mysql_native_password' |
dbサービスに保存されたテーブルデータをdockerボリュームを使用して永続化proxyサービスのポート番号は、80番をホスト側に公開(backendサービスのポートはホスト側に公開しない)
※backendサービスのポートは、開発段階では確認用として、ポート8000番をホスト側に公開してください。ただし、最終的には、proxyサービスがホスト側に公開するので、backendサービスのポートをホスト側に公開する必要はありません。- 2つのカスタムネットワーク(
backnet,frontnet)を使用db,backend間:backnetbackend,proxy間:frontnet
※Composeのネットワークについてはこちら(Networking in Compose)を参照ください。
- コンテナが停止すると常に再起動するように設定
- サービスの起動順序は、
db,backend,proxyの順とする。
また、dbサービスにおいて、以下のようなhealthcheckを定義し、service_healthyをbackendサービス起動の条件としてください。
|
1 2 3 4 5 |
healthcheck: test: ['CMD-SHELL', 'mysqladmin ping -h 127.0.0.1 --password="$$(cat /run/secrets/db-password)" --silent'] interval: 3s retries: 5 start_period: 30s |
進め方について
上記要件を踏まえて、以下ステップを参考にComposeファイルを作成してみてください。
1. backendサービス単体を定義し、ホストにポート番号8000で公開
localhost:8000にアクセスすると、エラーが表示されるはずです。
2. dbサービス単体を定義し、エラーなく起動することを確認サービスの設定に関しては、
dbbackend/hello.pyを参考にして設定すると良いでしょう。
3. dbサービスとbackendサービスを起動にアクセスすると、以下が表示されるばずです。
localhost:8000
|
1 2 3 4 |
Hello Blog post #1 Hello Blog post #2 Hello Blog post #3 Hello Blog post #4 |
4. proxyサービスの追加
localhost:80にアクセスすると、上記と同じものが表示されるはずです。
5. 残りの要件を満たすように設定
Composeファイルの書き方や、docker composeコマンドについては以下公式ドキュメントのページを参考にしてください。
トラブルシューティング
ログの確認
サービスが正しく起動しない場合は、ログを確認して原因を調査しましょう。以下コマンドが使用できます。
Dockerオブジェクトの情報取得
docker inspect <NAME>で、Dockerオブジェクト(コンテナ、ネットワーク、ボリュームなど)の情報を見ることができます。例えば、volumeのマウント先や、環境変数の設定などが正しく設定されているのかを確認できます。
ボリュームについて
ボリュームは、コンテナ内の任意のディレクトリやファイルにマウントすることで、コンテナ内のデータを保存し永続化します。このボリュームの性質上、仮に、サービスにエラーが発生した場合も、そのエラー時の間違ったデータがボリュームに保存されます。この状態で、新たにコンテナを作成した場合、この間違ったデータが保存されるボリュームがコンテナ内にマウントされてしまいます。
この状態を避けるために、基本的に開発中は、コンテナ起動前にボリュームを削除することをおすすめします。以下コマンドを使用できます。
docker compose down -v
-vオプションによりdocker compose up時に作成されたコンテナ、ネットワークの削除に加えて、ボリュームの削除が可能です。docker volume rm <VOLUME>
アプリケーションの実行
Docker composeコマンドを使用して、アプリケーションを実行してください。
また、以下コマンドにより各サービスの稼動を確認してください。
|
1 2 3 4 5 6 7 |
$ docker compose ps Name Command State Ports ------------------------------------------------------------------------------------------------------------------- nginx-flask-mysql_backend_1 flask run Up 0.0.0.0:8000->8000/tcp,:::8000->8000/tcp nginx-flask-mysql_db_1 docker-entrypoint.sh mysqld Up (healthy) 3306/tcp, 33060/tcp nginx-flask-mysql_proxy_1 nginx -g daemon off; Up 0.0.0.0:80->80/tcp,:::80->80/tcp |
そして、ブラウザで http://localhost:80/ を開き(または、curl localhost:80)以下のように表示されるかを確認してください。
|
1 2 3 4 |
Hello Blog post #1 Hello Blog post #2 Hello Blog post #3 Hello Blog post #4 |
チャレンジ問題
上記演習において、Flaskのサーバー機能を使用していました。Flaskのサーバー機能は開発用であり、本番環境向けではないため、WSGIサーバーを使用するのが一般的です。backendサービスのログにおいても、以下のような警告が表示されているはずです。
- WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
そこで、Python WSGIサーバーであるGunicornライブラリーを使用して、この警告を出ないようにしてください。
まとめ
本演習では、Docker composeを使い、ウェブアプリケーション(nginx-flask-mysql)を定義するcompose.yamlファイルを作成し、実行しました。演習を通して、compose.yamlファイルの書き方、composeコマンドの使い方を学ぶことが出来たと思います。
今回使用したawesome-composeレポジトリはDockerの公式ドキュメントで紹介されているレポジトリです。多くのDocker composeの例があるので、是非学習に役立ててください。




