このブログ記事では、DockerにおけるDocker Composeについて紹介します。

前回の記事では、Dockerfileからイメージをビルドし、そのイメージからDockerコンテナを実行する方法を紹介しました。 また、開発中のコード変更ごとに新しいイメージを作成しないためにボリュームを使用する方法についても説明しました。 今回の記事では、これらの機能をより簡単に実行できるDocker Composeを紹介します。
Docker Compose
小規模なプロジェクトでは、docker run --name myserver_c myserver -d -p 3000:4000 -v /Users/.../server:/app -v /app/node_modules
のようなコマンドを手動で入力して、
イメージを実行し、コンテナをインスタンス化することは容易です。しかし、フロントエンドとバックエンド用に複数のコンテナを実行したり、水平スケーリングを行ったりする場合、
この長いコマンドを手動で入力するのは面倒で、何よりもエラーが発生しやすくなります。解決策の一つはバッシュスクリプトを設定することですが、
Dockerはより良いネイティブソリューションであるDocker Composeを提供しており、docker-compose.yaml
で以下のようにビルドを設定できます。
version: "3.8" # Docker Composeのバージョン
services:
myserver: # サービス名
build: ./server # Dockerfileのディレクトリー
container_name: myserver_c
ports:
- "3000:4000" # ローカルポート:コンテナポート
volumes:
- ./server:/app # ボリューム (relative local path: container path)
- /app/node_modules # 匿名ボリューム
上記のdocker-compose.yaml
の例では、<directory_name>_myserver
イメージ(ディレクトリ名はYAMLファイルが存在するディレクトリの名前)を作成し、
ポートとボリュームのマッピングを持つmyserver_c
コンテナを起動します。イメージのビルドでは、build
セクション下のパス(この場合は./server
)を探し、
そのディレクトリ内のDockerfileを使用します。イメージをビルドして実行するにはdocker compose up
コマンドを使用し、コンテナを停止するにはdocker compose down
を使用できます。
コンテナを停止する際、関連するイメージとボリュームも一緒に削除するにはdocker compose down -rmi all -v
を使用できます。
水平スケーリング
Docker Composeを使用すると、複数のディレクトリ内のDockerfileから複数のイメージをビルドし、それらを実行して一度に複数のコンテナを起動できます。 次の例は、水平スケーリングのために同じDockerfileから複数のイメージとコンテナを起動する例です。
version: "3.8"
services:
myserver1:
build: ./server
container_name: myserver_c1
ports:
- "3000:4000"
myserver2:
build: ./server
container_name: myserver_c2
ports:
- "3001:4000"
myserver3:
build: ./server
container_name: myserver_c3
ports:
- "3002:4000"
上記では同じDockerfileを使用して3つのイメージとコンテナを作成し、ローカルポート3000
、3001
、3002
にマッピングしています。
これらのローカルポートにトラフィックを分散するリバースプロキシやロードバランサーを設定することで、水平スケーリングを実現できます。
ただし、リバースプロキシもコンテナ化することができ、これによりサーバーをローカルポートに公開せずに、コンテナポート経由で直接サーバーと通信できるようになります。
また、以下のようにreplicas
フィールドを使用することもできるようになります:
version: "3.8"
services:
myserver:
build: ./server
container_name: myserver_c
deploy:
replicas: 3
reverse-proxy:
# ...リバースプロキシの設定 (省略)
上記では、サーバー用に3つのコンテナを自動的に起動しますが、これらはローカルポートには公開されません。
これにより、ローカルポートに公開されているリバースプロキシからのアクセスに制限できます(このリバースプロキシの実装については、この記事では省略し、次回の記事で取り上げます)。
上記の実装では、docker compose up
の後にdocker compose scale myserver=6
などを使用して、サービスmyserver
の数を動的に設定することができ、
柔軟な水平スケーリングが可能になります。
イメージの依存関係
複数のイメージを設定する際、特定の順序でイメージをビルドして実行することが重要な場合があります。
例えば、トラフィックを分散するリバースプロキシを設定する前にサーバーをビルドする必要があり、
フロントエンドをビルドする前にバックエンドWebサーバーをビルドする必要があります。depends_on
フィールドを使用して、
イメージのビルドと実行の順序を以下のように設定できます:
version: "3.8"
services:
backend:
build: ./backend
container_name: backend_c
ports:
- "4000:4000"
frontend:
build: ./frontend
container_name: frontend_c
ports:
- "3000:3000"
depends_on:
- backend
上記のように、問題のサービスの前にビルドして実行する必要があるサービスの名前をdepends_on
フィールドにリストすることで、
バックエンドサービスがフロントエンドサービスの設定前にビルドされ実行されることを保証できます。
結論
この記事では、Docker Composeとその基本機能を紹介し、サービスの構成とビルドを簡単に行う方法を説明しました。 この記事で触れなかったDocker Composeの機能はまだ多くありますので、詳細については下記の公式ドキュメントを参照することをお勧めします。
リソース
- Docker. n.d. Docker Compose, Docker Docs.
- Net Ninja. 2022. Docker Crash Course #11 - Docker Compose. YouTube.