Docker Compose を使用したローカル開発
この記事の英語版に更新があります。ご覧の翻訳には含まれていない変更点があるかもしれません。
最終更新日 2023年11月06日(月)
Table of Contents
Docker Compose は、マルチコンテナ Docker アプリケーションを定義および実行するためのツールです。Docker Compose がどのようにローカル開発に優れているか、開発のために Docker image を Heroku にプッシュする方法、その他のお役立ち情報について説明します。
Docker Compose の導入
単純な Python ベースのマルチコンテナアプリケーションから始めましょう。このサンプルアプリは、Redis、キャッシュ用の Web フロントエンド、およびデータベースとしての Postgres から構成されています。Docker、Redis、Postgres はそれぞれ別のコンテナで実行されます。
Docker Compose を使用して、環境変数、アクセスできる必要のあるポート、マウントするボリュームなど、ローカル開発環境を定義できます。docker-compose
CLI が使用するものはすべて、docker-compose.yml
で定義します。
アプリケーションの docker-compose.yml
は次のとおりです:
version: '2'
services:
web:
build: .
ports:
- "5000:5000"
env_file: .env
depends_on:
- db
volumes:
- ./webapp:/opt/webapp
db:
image: postgres:latest
ports:
- "5432:5432"
redis:
image: redis:alpine
ports:
- "6379:6379"
Web サービス
最初のセクションでは Web サービスを定義します。ここではポート 5000 を開き、.env
で定義されている環境変数を設定し、ローカルコードディレクトリをボリュームとしてマウントします。
services:
web:
build: .
ports:
- "5000:5000"
env_file: .env
depends_on:
- db
volumes:
- ./webapp:/opt/webapp
データベースサービス
次のサービスは Postgres データベースであり、ポート 5432 を開いて、最新の Docker Hub の公式 Postgres イメージを使用します。
db:
image: postgres:latest
ports:
- "5432:5432"
Redis サービス
このセクションでは Redis サービスを定義します。ポート 6379 を開き、Docker Hub の公式 Redis イメージを使用します。
redis:
image: redis:alpine
ports:
- "6379:6379"
ローカル開発環境が docker-compose.yml
で定義されたため、1 つのコマンドで 3 つのサービスすべてを迅速に起動できます。
$ docker-compose up
このコマンドは、3 つのコンテナがすべて実行中であることを確認するものです。
$ docker ps
CONTAINER ID IMAGE COMMAND
8e422ff92239 python_web "/bin/sh -c 'python a"
4ac9ecc8a2a3 python_db "/docker-entrypoint.s"
2cbc8febd074 redis:alpine "docker-entrypoint.sh"
Docker Compose のメリット
Docker Compose で Docker を使用し、ローカル開発環境を定義することには、いくつかのメリットがあります。
- Redis および Postgres を Docker コンテナ内で実行すれば、ローカルマシンにソフトウェアをインストールしたり管理したりする必要がなくなります。
- ローカル開発環境全体をソース管理にチェックインでき、他の開発者がプロジェクトで協力しやすくなります。
- 次の 1 つのコマンドでローカル開発環境全体を迅速に起動できます:
docker-compose up
。
Heroku へのコンテナのプッシュ
ビルドに満足している場合は、Web フロントエンドをデプロイ用に直接 Heroku Container Registry にプッシュできます。一般的な CI/CD ツールもサポートしています。
$ heroku container:push web
Python アプリケーションは Postgres および Redis に依存し、これらは Heroku にプッシュしません。その代わりに、本番環境では Heroku アドオンを使用します。
本番環境での Heroku Add-ons の使用
- ローカル開発の場合: Postgres や Redis などの正式な Docker image を使用します。
- ステージングおよび本番環境の場合: Heroku Postgres や Heroku Data for Redis などの Heroku Add-ons を使用します。
ローカルで正式な Docker image を使用し、本番環境で Heroku Add-ons を使用すると、両方の長所を生かすことができます。
- パリティ (同等性): 本番環境で使用するサービスと同じものをローカルマシンで使用することによってパリティ (同等性) を得ることができます。
- 運用上の負担の削減: アドオンを使用することにより、Heroku またはアドオンプロバイダーがレプリケーション、可用性、バックアップに関する運用上の負担を引き受けます。
Docker Compose のお役立ち情報
ローカル開発に Docker Compose を使用する場合は、これらのお役立ち情報を知っておくと便利です。
.env
ファイルを作成して資格情報がソースコードコントロールにチェックインされないようにする
Docker および Docker Compose を使用することで、ローカル開発環境の設定をソースコードコントロールにチェックインすることができます。機密情報を含む資格情報を扱うには、資格情報を含む .env 環境ファイルを作成し、Compose YAML 内でこれを参照します。.env
を .gitignore
および .dockerignore
ファイルに追加すると、ソースコード管理にチェックインされず、Docker image にも含まれません。
services:
web:
env_file: .env
イメージの再構築を回避するための、ボリュームとしてのコードのマウント
コードを変更するたびに、Docker image を再構築する必要があります。この再構築は手動で行う必要があり、時間がかかる可能性があります。この問題を解決するには、コードをボリュームとしてマウントします。これで、コードが変更されたときに再構築する必要はなくなりました。
services:
web:
volumes:
- ./webapp:/opt/webapp
ホスト名を使用してコンテナに接続する
デフォルトでは、Docker Compose はアプリ用の単一ネットワークをセットアップします。Compose YAML 内でサービスに名前をつけると、ホスト名が作成され、これを使用してサービスに接続できます。
Compose YAML 内のサービスは次のとおりです。
services:
web:
redis:
db:
接続文字列は次のとおりです。
postgres://db:5432
redis://redis:6379
バックグラウンドモードでの Compose の実行
docker-compose up
を実行すると、プロジェクトはフォアグラウンドで実行し、サービスの出力を表示します。ctrl+c
を使用してサービスのグレースフルシャットダウンを実行できます。
あまり知られていない手段ですが、docker-compose up -d
を使用してコンテナをバックグラウンドで起動できます。docker-compose down
を使用して Compose の設定を解除できます。バックグラウンドモードで実行中のサービスのログは、docker-compose logs
を使用して確認します。
複数の Dockerfile を持つプロジェクト構造
複数のサービスがある場合、プロジェクト内の Docker image ごとにサブディレクトリを作成し、Dockerfile をそれぞれのディレクトリに保管することをお勧めします。
/web/Dockerfile
/redis/Dockerfile
/db/Dockerfile
/worker/Dockerfile
プロジェクトのホームディレクトリにすべての Dockerfile を保存することはお勧めしません。サービスの区別が困難になるためです。
非ルートユーザーとしてのコンテナの実行
コンテナを非ルートユーザーとして実行することは、良いセキュリティ習慣です。また、Heroku にプッシュしたコンテナはルートアクセスなしで実行されます。非ルートユーザーとしてローカルでコンテナをテストすることで、これらが Heroku 本番環境で機能することを確認できます。コンテナレジストリのドキュメントで詳細を確認してください。