Docker Compose を使用したローカル開発
この記事の英語版に更新があります。ご覧の翻訳には含まれていない変更点があるかもしれません。
最終更新日 2022年07月15日(金)
Table of Contents
Docker Compose は、マルチコンテナ Docker アプリケーションを定義および実行するためのツールです。この記事では、Docker Compose がローカル開発に優れている理由、開発のために Docker イメージを Heroku にプッシュする方法、および Compose のヒントとコツについて説明します。
Docker Compose の導入
単純な Python ベースのマルチコンテナアプリケーションから始めましょう。 このサンプルアプリは、Web フロントエンド、キャッシュ用の Redis、およびデータベースとしての Postgres から構成されています。 Docker では、Web フロントエンド、Redis、および Postgres はそれぞれ別のコンテナで実行します。
Docker Compose を使用して、環境変数、アクセスできる必要のあるポート、およびマウントするボリュームなど、ローカル開発環境を定義できます。 すべてが docker-compose.yml
で定義されており、これは docker-compose
CLI で使用されます。
次にアプリケーションの 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
db サービス
次のサービスは 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 コンテナレジストリにプッシュできます (一般的な CI/CD ツールもサポートされています)。
$ heroku container:push web
Python アプリケーションは Postgres および Redis に依存し、これらは Heroku にプッシュしません。 その代わりに、本番環境では Heroku アドオンを使用します。
本番環境での Heroku アドオンの使用
- ローカル開発の場合: Postgres や Redis などの正式な Docker イメージを使用します。
- ステージングおよび本番環境の場合: Heroku Postgres や Heroku Data for Redis などの Heroku アドオンを使用します。
ローカルで正式な Docker イメージを使用し、本番環境で Heroku アドオンを使用すると、両方の長所を生かすことができます。
- パリティ (同等性): 本番環境で使用するサービスと同じものをローカルマシンで使用することによってパリティ (同等性) を得ることができます。
- 運用上の負担の削減: アドオンを使用することにより、Heroku (またはアドオンプロバイダー) が複製、可用性、バックアップに関する運用上の負担を引き受けます。
Docker Compose のヒントとコツ
Docker Compose をローカル開発で使用する際に、作業を成功させるために役立つと思われるいくつかのヒントとコツがあります。
.env ファイルを作成して資格情報がソースコードコントロールにチェックインされないようにする
Docker および Docker Compose を使用することで、ローカル開発環境の設定をソースコードコントロールにチェックインすることができます。 機密情報を含む資格情報を扱うには、資格情報を含む .env 環境ファイルを作成し、Compose YAML 内でこれを参照します。 .env は .gitignore および .dockerignore ファイルに追加されるため、ソースコードコントロールにチェックインされたり Docker イメージに含められたりすることはありません。
services:
web:
env_file: .env
イメージの再構築を回避するためのボリュームとしてのコードのマウント
コードに変更を加えたときはいつでも、Docker イメージを再構築する必要があります (これは手動ステップであり、時間がかかることがあります)。 この問題を解決するには、コードをボリュームとしてマウントします。 これで、コードが変更されたときに再構築する必要はなくなりました。
services:
web:
volumes:
- ./webapp:/opt/webapp
ホスト名を使用してコンテナに接続する
デフォルトでは、Compose はアプリ用の単一ネットワークをセットアップします。 Compose YAML 内でサービスに名前をつけると、ホスト名が作成され、後でこれを使用してサービスに接続できます。
Compose YAML 内のサービスは次のとおりです。
services:
web:
redis:
db:
接続文字列は次のとおりです。
postgres://db:5432
redis://redis:6379
バックグラウンドモードでの Compose の実行
docker-compose up
を実行すると、プロジェクトはフォアグラウンドで実行し、サービスの出力を表示します。 ctrl+c
を使用してサービスのグレースフルシャットダウンを実行できます。
あまり知られていないオプションの 1 つとして、docker-compose up -d
を使用してコンテナをバックグラウンド (つまり分離モード) で開始する方法があり、docker-compose down
を使用して Compose 設定を停止できます。 バックグラウンドモードで実行中のサービスのログは、docker-compose logs
を使用して確認します。
複数の Dockerfile を持つプロジェクト構造
複数のサービスがある場合、プロジェクト内の Docker イメージごとにサブディレクトリを作成し、Dockerfile をそれぞれのディレクトリに保管することをお勧めします。
/web/Dockerfile
/redis/Dockerfile
/db/Dockerfile
/worker/Dockerfile
プロジェクトのホームディレクトリにすべての Dockerfile を保存することはお勧めしません。サービスの区別が困難になるためです。
非ルートユーザーとしてのコンテナの実行
セキュリティ上、非ルートユーザーとしてコンテナを実行することをお勧めしますが、Heroku にプッシュするコンテナはルートアクセス権を使用せずに実行することがより重要です。 非ルートユーザーとしてローカルでコンテナをテストすることで、これらが Heroku 本番環境で機能することを確認できます。 コンテナレジストリのドキュメントで詳細を確認してください。