Day 4: ローカル開発環境をDocker Composeで構築しよう 💻
皆さん、こんにちは!30日集中講座、Day 4へようこそ。
昨日、Dockerfileを使ってアプリケーションのコンテナイメージを作成する方法を学びました。しかし、実際のアプリケーションは、Webサーバー、データベース、キャッシュサーバーなど、複数のコンテナが連携して動くことが多いです。
そこで登場するのが、複数のコンテナをまとめて管理・実行するためのツール、「Docker Compose」です。
1. Docker Composeとは?
Docker Composeは、複数コンテナで構成されるアプリケーションを定義し、実行するためのツールです。
その定義は、docker-compose.yml
というYAMLファイルに記述します。このファイルに「どのイメージを使うか」「どのポートを公開するか」「コンテナ同士をどう連携させるか」といった情報をまとめて書くことで、たった一つのコマンドでアプリケーション全体を起動できるようになります。
車の製造に例えると、これまでは部品(コンテナ)を一つずつ手作業で組み立てていたのに対し、Docker Composeを使えば、設計図(docker-compose.yml
)を渡すだけで、車(アプリケーション全体)が自動で組み立てられるイメージです。
2. docker-compose.yml
ファイルの基本構造
docker-compose.yml
ファイルは、非常にシンプルで直感的に理解できます。
基本的な構造は以下の通りです。
# Docker Compose V2形式ではバージョン指定は省略が推奨
# version: '3.8'
services:
<サービス名1>:
...
<サービス名2>:
...
-
services
: アプリケーションを構成する各サービスを定義するセクションです。
Docker Compose V2(Docker Engine 1.27以降)では、version
の指定は不要となり、docker compose
(ハイフンなし) というコマンド形式が新しい標準となっています。
3. サンプルプロジェクトで学ぶ実践的な使い方
ここでは、シンプルなPython Webアプリケーションとデータベースを連携させる例を見ていきましょう。
プロジェクトのファイル構成
my-web-app/
├── app.py
├── requirements.txt
├── .env
├── .gitignore
├── Dockerfile
└── docker-compose.yml
docker-compose.yml
とは別に、環境変数を定義する.env
ファイルを用意します。
.env
ファイルの活用
.env
ファイルに機密情報や環境ごとの設定を記述することで、docker-compose.yml
をクリーンに保つことができます。
# .env ファイルの例
DATABASE_URL=postgresql://postgres:secret_password@db:5432/mydatabase
POSTGRES_USER=postgres
POSTGRES_PASSWORD=secret_password
POSTGRES_DB=mydatabase
FLASK_ENV=development
FLASK_DEBUG=1
重要な注意: .env
ファイルはパスワードなどの機密情報を含むため、必ず.gitignore
に追加し、Gitリポジトリにコミットしないようにしてください。
# .gitignore に追加すべきファイル
.env
.env.local
.env.production
docker-compose.yml
の定義
services:
web:
build: .
ports:
- "5000:5000"
volumes:
# 開発効率を上げるため、ホストのコードをコンテナにマウント
- .:/app
# node_modulesなど重いディレクトリは除外してビルドを高速化
- /app/node_modules
env_file:
- .env
depends_on:
- db
environment:
# Pythonの出力をリアルタイムに表示する設定
- PYTHONUNBUFFERED=1
db:
image: postgres:13
volumes:
# ボリュームを使ってデータを永続化
- postgres_data:/var/lib/postgresql/data
env_file:
- .env
# dbサービスはポートを外部に公開しない
# ports:
# - "5432:5432"
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 30s
timeout: 10s
retries: 3
volumes:
postgres_data:
depends_on
と healthcheck
depends_on
は、コンテナの起動順序のみを保証します**。データベースが起動して接続可能になるまでは待ちません。実務では、healthcheck
を使ってコンテナの準備完了を待つ工夫が必要です。
4. Docker Composeコマンドと実践向けTips
docker-compose.yml
ファイルを作成したら、あとは簡単なコマンドを実行するだけです。ここでは、新しいDocker CLIの docker compose
(ハイフンなし) に統一します。
開発時の典型的なワークフロー
-
開発開始時: アプリケーションをバックグラウンドで起動します。
docker compose up -d
-
ログ確認:
# 全サービスのログを確認 docker compose logs # 特定のサービスのログをリアルタイムで追跡 docker compose logs -f web
-
コンテナ内へのアクセス:
# webサービスコンテナ内でbashシェルを実行 docker compose exec web bash
-
開発終了時: アプリケーションを停止し、コンテナとデータを削除します。
# ボリュームのデータを残してコンテナを削除 docker compose down # ボリュームのデータも一緒に削除 docker compose down -v
5. よくある問題と解決策
-
ポート競合エラーが発生した場合
「Port is already allocated」というエラーが出たら、ホスト側のポート番号を変更します。ports: - "15432:5432" # ホスト側のポートを5432から15432に変更
-
イメージを強制的に再ビルドしたい場合
キャッシュを使わず、Dockerfileからイメージを再構築します。docker compose build --no-cache web
-
全てをクリーンアップして再起動したい場合
コンテナとボリュームを全て削除してから再起動します。docker compose down -v docker compose up --build
6. まとめ:Docker Composeでローカル開発は劇的に変わる
今日は、Docker Composeを使って複数コンテナのアプリケーションを簡単に構築・管理する方法を学びました。
-
docker-compose.yml
: サービス構成をコードとして管理できます。 -
docker compose up
: アプリケーション全体を一発で起動できます。 -
docker compose down
: アプリケーション全体を一発で停止・削除できます。
これで、皆さんは単一のコンテナだけでなく、複数コンテナで構成されるアプリケーションをローカルで自在に扱えるようになりました。
次回の予告
Day 5: ボリュームとネットワーク:コンテナ間でデータを共有し、通信する方法
それでは、また明日お会いしましょう!