Docker ComposeのためのYAML:設定パターンとヒント
Docker Composeは、マルチコンテナアプリケーションを定義するためにYAMLを使用します。適切に構造化された docker-compose.yml は、スムーズな開発環境とコンテナの問題を何時間もデバッグすることの違いを生みます。このガイドでは、必須のパターンと一般的な落とし穴を解説します。
基本構造
services:
web:
image: nginx:alpine
ports:
- "80:80"
volumes:
- ./html:/usr/share/nginx/html
depends_on:
- api
api:
build: ./api
ports:
- "3000:3000"
environment:
DATABASE_URL: postgres://db:5432/myapp
depends_on:
- db
db:
image: postgres:16
volumes:
- pgdata:/var/lib/postgresql/data
environment:
POSTGRES_DB: myapp
POSTGRES_PASSWORD: secret
volumes:
pgdata:
環境変数
インライン
services:
api:
environment:
NODE_ENV: production
PORT: "3000"
DEBUG: "false"
ファイルから
services:
api:
env_file:
- .env
- .env.local # .envの値をオーバーライド
変数置換
ホストの環境変数を参照:
services:
api:
image: myapp:${TAG:-latest} # デフォルトは "latest"
environment:
API_KEY: ${API_KEY} # 必須 - 設定されていない場合失敗
LOG_LEVEL: ${LOG_LEVEL:-info} # デフォルトは "info"
ネットワーク
カスタムネットワーク
services:
web:
networks:
- frontend
api:
networks:
- frontend
- backend
db:
networks:
- backend
networks:
frontend:
backend:
internal: true # 外部アクセス不可
同じネットワーク上のサービスは、サービス名で互いに通信できます。db サービスは api からのみアクセス可能で、web からはアクセスできません。
ポートマッピング
ports:
- "8080:80" # ホスト:コンテナ
- "443:443"
- "127.0.0.1:3000:3000" # localhostにのみバインド
- "3000" # ランダムなホストポート
ボリューム
名前付きボリューム(永続的)
services:
db:
volumes:
- pgdata:/var/lib/postgresql/data
volumes:
pgdata:
driver: local
バインドマウント(開発用)
services:
api:
volumes:
- ./src:/app/src # ソースコード
- /app/node_modules # 匿名ボリューム(オーバーライド防止)
匿名ボリュームパターン (/app/node_modules) は、ホストのバインドマウントがコンテナにインストールされた依存関係を上書きするのを防ぎます。
ヘルスチェック
services:
db:
image: postgres:16
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
timeout: 5s
retries: 5
start_period: 30s
api:
depends_on:
db:
condition: service_healthy
これにより、api はコンテナが起動した時ではなく、db がヘルスチェックに合格した後にのみ起動します。
拡張フィールド(DRYパターン)
x- プレフィックスのフィールドとYAMLアンカーを使用して繰り返しを削減:
x-common: &common
restart: unless-stopped
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"
x-env: &common-env
TZ: UTC
LOG_FORMAT: json
services:
api:
<<: *common
build: ./api
environment:
<<: *common-env
PORT: "3000"
worker:
<<: *common
build: ./worker
environment:
<<: *common-env
QUEUE: default
YAMLアンカーの詳細については、YAMLアンカーとエイリアスガイドをご覧ください。
マルチステージCompose
開発環境 vs 本番環境
# docker-compose.yml (ベース)
services:
api:
build: ./api
environment:
DATABASE_URL: postgres://db:5432/myapp
# docker-compose.override.yml (開発用 - 自動読み込み)
services:
api:
volumes:
- ./api/src:/app/src
environment:
NODE_ENV: development
DEBUG: "true"
ports:
- "3000:3000"
- "9229:9229" # デバッグポート
# docker-compose.prod.yml
services:
api:
environment:
NODE_ENV: production
deploy:
replicas: 3
# 開発環境(オーバーライドを自動読み込み)
docker compose up
# 本番環境
docker compose -f docker-compose.yml -f docker-compose.prod.yml up
よくある落とし穴
1. 引用符なしのポート番号
# 危険 - YAMLは80:80を60進数として解釈する
ports:
- 80:80
# 安全 - 常に引用符で囲む
ports:
- "80:80"
2. 真偽値の環境変数
# 誤り - YAMLが真偽値に変換する
environment:
DEBUG: true # Python Trueになり、文字列 "true" ではない
# 正しい - すべての環境変数値を引用符で囲む
environment:
DEBUG: "true"
3. depends_onのタイミング
depends_on はコンテナの起動のみを待ち、準備完了は待ちません:
# コンテナは起動するがDBが準備できていない可能性がある
depends_on:
- db
# ヘルスチェックを待つ
depends_on:
db:
condition: service_healthy
YAMLバリデーターでDocker Composeファイルを検証しましょう。
FAQ
docker-compose.yml と compose.yml の違いは何ですか?
どちらのファイル名も使用できます。compose.yml はDockerが推奨する新しい命名規則です。docker-compose.yml はレガシーな名前です。Docker Compose v2以降は両方を検索し、両方存在する場合は compose.yml を優先します。新しいプロジェクトでは compose.yml を使用してください。
本番環境でDocker Composeを使うべきですか?
Docker Composeは開発やシンプルなデプロイに最適です。大規模な本番環境では、Docker Swarm(Composeファイルをネイティブに使用)やKubernetesを検討してください。Composeの利点は、開発の設定が本番に直接反映されるため、環境の差異が減ることです。
関連リソース
- YAMLバリデーター — Docker Compose YAMLの検証
- YAMLアンカーとエイリアス — DRY設定パターン
- YAML構文チュートリアル — YAMLの基礎