Docker: Compose の高度なオーケストレーション

最終更新:2026-08-26

開発、テスト、本番——1 つの Compose ファイルで 3 つの環境をすべて扱えます。

1. 学べること



2. テックリードの実話

(1) 悩み: 3 つの環境、3 つの設定ファイル

Charlie は開発・テスト・本番の 3 環境のために別々の Compose 設定を維持しなければなりません。開発環境ではホットリロードとデバッグツールが必要、テスト環境では完全なサービススタックが必要、本番環境ではリソース制限と複数レプリカが必要です。3 つの別々の YAML ファイルには重複するコードが多く、どこか 1 つを変更するには 3 つのファイルをすべて修正しなければなりません。

(2) プロファイル + override による解決

Charlie は「1 つの基本設定 + 環境別オーバーライド」という構成を、プロファイルとオーバーライドファイルで実現しました。

BASH
# 開発: dev プロファイル + dev オーバーライドを有効化
docker compose --profile dev -f docker-compose.yml -f docker-compose.dev.yml up -d

# 本番: prod オーバーライドのみ
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d

(3) 成果: 3 ファイル → 1 + 2 ファイル

完全に独立した 3 つのファイルから、1 つの基本ファイル + 2 つの差分オーバーライドファイルへ。共通設定を 1 か所でだけ管理すればよくなりました。



3. プロファイル: 複数環境の設定

(1) プロファイルの仕組み

100%
graph TB
    BASE["docker-compose.yml<br/>基本サービス"] --> DEV["--profile dev<br/>+ dev ツール(ホットリロード、adminer)"]
    BASE --> TEST["--profile test<br/>+ テストランナー(selenium)"]
    BASE --> PROD["--profile prod<br/>+ 監視(prometheus、grafana)"]

▶ サンプル: --profile dev を有効化 (難易度: ⭐⭐)

YAML
# プロファイル付き docker-compose.yml
services:
  api:
    build: .
    ports:
      - "5000:5000"
    environment:
      - FLASK_ENV=development

  db:
    image: postgres:15-alpine
    volumes:
      - pg-data:/var/lib/postgresql/data

  # dev 専用: データベース管理 UI
  adminer:
    image: adminer
    ports:
      - "8081:8080"
    profiles: ["dev"]
    depends_on: [db]

  # dev 専用: flask debug によるホットリロード
  api-dev:
    build:
      context: .
      dockerfile: Dockerfile.dev
    volumes:
      - ./src:/app
    ports:
      - "5000:5000"
      - "5678:5678"   # デバッグポート
    environment:
      - FLASK_DEBUG=1
    profiles: ["dev"]

  # prod 専用: Prometheus 監視
  prometheus:
    image: prom/prometheus
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml
    ports:
      - "9090:9090"
    profiles: ["prod"]

volumes:
  pg-data:
BASH
# 開発: 基本サービス + dev プロファイル
docker compose --profile dev up -d

# 本番: 基本サービス + prod プロファイル
docker compose --profile prod up -d

# 基本サービスのみ(プロファイルなし)
docker compose up -d

(2) プロファイルと override の比較

比較項目 プロファイル override ファイル
ファイル数 1 ファイル 2〜3 ファイル
有効化方法 --profile xxx -f base.yml -f override.yml
向いている場面 サービスの増減 設定の差分が大きい
組み合わせ 複数プロファイルを同時有効可 順番にマージ


4. override ファイルのマージ

▶ サンプル: override ファイルによる設定の上書き (難易度: ⭐⭐⭐)

YAML
# docker-compose.yml(基本設定)
services:
  api:
    build: .
    environment:
      FLASK_ENV: production
    restart: unless-stopped

  db:
    image: postgres:15-alpine
    volumes:
      - pg-data:/var/lib/postgresql/data
    restart: unless-stopped

volumes:
  pg-data:
YAML
# docker-compose.dev.yml(dev 用オーバーライド)
services:
  api:
    environment:
      FLASK_ENV: development
      FLASK_DEBUG: "1"
    volumes:
      - ./src:/app     # ホットリロード: ソースコードをマウント
    ports:
      - "5678:5678"    # デバッグポート

  # dev 専用サービス
  adminer:
    image: adminer
    ports:
      - "8081:8080"
YAML
# docker-compose.prod.yml(prod 用オーバーライド)
services:
  api:
    deploy:
      replicas: 3
      resources:
        limits:
          cpus: "1.0"
          memory: 512M
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:5000/health"]
      interval: 30s
      timeout: 5s
      retries: 3

  # prod 専用: Nginx リバースプロキシ
  nginx:
    image: nginx:1.25-alpine
    ports:
      - "80:80"
    volumes:
      - ./nginx.prod.conf:/etc/nginx/conf.d/default.conf
    depends_on:
      - api
BASH
# 開発
docker compose -f docker-compose.yml -f docker-compose.dev.yml up -d

# 本番
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d

# マージ後の設定をプレビュー(ドライラン)
docker compose -f docker-compose.yml -f docker-compose.prod.yml config


5. 水平スケーリング

▶ サンプル: --scale でレプリカ数を指定 (難易度 ⭐⭐)

BASH
# API サービスを 3 レプリカにスケール
docker compose up -d --scale api=3

# 動作中のスタックを動的にスケール
docker compose up -d --scale api=5

(1) スケーリング時の注意点

問題 原因 解決策
ポート競合 複数レプリカが同じホストポートにマッピング エントリーポイント(Nginx)のみ公開し、API はホストポートにマップしない
データ整合性 同じストレージへの複数書き込み ステートレスなサービスのみスケール対象にする、データベースを共有
負荷分散 複数レプリカへリクエストをどう分散するか Nginx upstream または Docker の組み込み DNS ラウンドロビン

▶ サンプル: デプロイ.replicas で宣言的にスケール (難易度: ⭐⭐)

YAML
services:
  api:
    build: .
    deploy:
      replicas: 3
      resources:
        limits:
          cpus: "0.5"
          memory: 256M
        reservations:
          cpus: "0.25"
          memory: 128M
    # スケール対象サービスにはポートをマップしない
    # ports: ["5000:5000"]  ← replicas > 1 の場合競合する

  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
    # Nginx upstream が api:5000 へ DNS ラウンドロビンで分散


6. リソース制限

(1) デプロイ.resources の設定

YAML
services:
  api:
    deploy:
      resources:
        limits:        # ハードリミット(超過時は強制終了)
          cpus: "1.0"
          memory: 512M
        reservations:  # ソフト保証(最小割り当て)
          cpus: "0.5"
          memory: 256M
フィールド 用途 超過時の挙動
limits.cpus CPU 上限 超過時、スロットリング
limits.memory メモリ上限 超過時、OOM Kill
reservations.cpus 最小 CPU 保証 スケジューリング保証
reservations.memory 最小メモリ保証 スケジューリング保証


7. 完全なサンプル: 3 環境向け Compose プロジェクト

YAML
# ============================================
# docker-compose.yml - 基本設定
# ============================================
services:
  api:
    build:
      context: .
      dockerfile: Dockerfile
    environment:
      DATABASE_URL: postgresql://postgres:${DB_PASSWORD:-secret}@db:5432/${DB_NAME:-myapp}
    depends_on:
      db:
        condition: service_healthy
    restart: unless-stopped
    networks:
      - backend

  db:
    image: postgres:15-alpine
    environment:
      POSTGRES_PASSWORD: ${DB_PASSWORD:-secret}
      POSTGRES_DB: ${DB_NAME:-myapp}
    volumes:
      - pg-data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 5s
      timeout: 5s
      retries: 5
    restart: unless-stopped
    networks:
      - backend

  # dev 専用: Adminer DB UI
  adminer:
    image: adminer
    ports:
      - "8081:8080"
    profiles: ["dev"]
    networks:
      - backend

volumes:
  pg-data:

networks:
  backend:
YAML
# ============================================
# docker-compose.prod.yml - 本番オーバーライド
# ============================================
services:
  api:
    deploy:
      replicas: 3
      resources:
        limits:
          cpus: "1.0"
          memory: 512M
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:5000/health"]
      interval: 30s
      timeout: 5s
      retries: 3

  nginx:
    image: nginx:1.25-alpine
    ports:
      - "80:80"
    volumes:
      - ./nginx.prod.conf:/etc/nginx/conf.d/default.conf
    depends_on:
      api:
        condition: service_healthy
    restart: unless-stopped
    networks:
      - backend
BASH
# 開発
docker compose --profile dev up -d

# 本番(3 レプリカ + Nginx + リソース制限)
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d

# スケールの確認
docker compose -f docker-compose.yml -f docker-compose.prod.yml ps


❓ よくある質問

Q プロファイルと override ファイルは同時に使えますか?
A はい、使えます。docker compose --profile dev -f docker-compose.yml -f docker-compose.dev.yml up -d のように、プロファイルと override ファイルを併用できます。プロファイルはサービスの追加・削除を管理し、override ファイルは設定の差分を管理する——両者は互いに補完し合います。
Q --scaledeploy.replicas のどちらが優先されますか?
A コマンドラインの --scale 引数が YAML の deploy.replicas より優先されます。両方が設定されている場合、--scale の値が YAML を上書きします。本番環境ではバージョン管理しやすい YAML 宣言を推奨し、デバッグ時の迅速な調整には --scale を使います。
Q サービスの起動順序を制御するには?
A depends_on + condition の組み合わせを使います。3 つの条件: ① service_started(デフォルト、起動のみ待つ)、② service_healthy(ヘルスチェック合格を待つ)、③ service_completed_successfully(初期化タスクの完了を待つ)。本番環境では常に service_healthy を使用してください。
Q 環境ごとに Compose ファイルの変数を切り替えるには?
A ${VAR:-default} + .env ファイルを使います。各環境に異なる .env ファイル(.env.dev / .env.prod)を用意し、起動時に --env-file で指定します: docker compose --env-file .env.prod up -d
Q 複数レプリカでポートはどう扱いますか?
A スケール対象サービスはホストポートにマッピングできません(複数レプリカで競合するため)。Nginx / HAProxy のみポートを公開し、API サービスは内部ネットワークで通信します。Nginx の upstream が Docker DNS のラウンドロビンで複数レプリカに自動分散します。

📖 まとめ


📝 練習問題

  1. 基本練習 (難易度 ⭐): 第 12 課のアプリケーションに対して、2 セットの override ファイル(dev 用と prod 用)を作成してください。dev 用にはホットリロード、prod 用にはリソース制限を追加します。
  2. 応用練習 (難易度 ⭐⭐): --scale api=3 で API サービスを 3 レプリカにスケールし、docker compose ps で確認してください。
  3. 挑戦 (難易度: ⭐⭐⭐): 3 レプリカの API に対する Nginx リバースプロキシを設定し、リクエストが異なるレプリカに分散されることを(各コンテナのログで)確認してください。
Web-Tutorial.com

Web-Tutorial 技術チーム

複数の開発者によって共同維持されているプログラミングチュートリアルプラットフォーム。各チュートリアルは専門分野の開発者が執筆・レビューしています。正確で信頼性の高いコンテンツを目指しています — 問題を見つけた場合はお知らせください。

100%