mcpField
D
docker-compose-setup

docker-compose-setup

github.com/seb1nクラウド・DevOps232121 回インストール11 週間前に更新
リポジトリ

docker-compose-setup について

Docker Compose を使ったマルチコンテナ構成の設計と設定を支援するスキルです。サービス依存関係、ネットワーク、永続ストレージ、ヘルスチェックに加え、開発環境と本番環境の設定分離を扱います。

主な機能

  1. 01サービスと依存関係を整理
  2. 02イメージ、ポート、変数を設定
  3. 03ネットワークとサービス検出を設定
  4. 04永続ボリュームとマウントを管理
  5. 05ヘルスチェックと起動順序を追加
  6. 06環境別のオーバーライドを作成

活用シーン

  1. 01複数サービスのアプリ構成を定義
  2. 02データベースやアップロードデータを永続化
  3. 03依存関係に応じてサービスを起動
  4. 04開発環境と本番環境の設定を分離

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/seb1n/awesome-ai-agent-skills --skill docker-compose-setup

インストール後、Claude Code で/docker-compose-setupを入力して読み込まれたか確認します。

詳細

Docker Compose のセットアップ

このスキルを使うと、エージェントは Docker Compose で複数コンテナーから成るアプリケーションスタックを設計、構成できます。エージェントは、適切なネットワーク設定、ボリューム管理、ヘルスチェック、環境ごとのオーバーライドを用いて、Web サーバー、データベース、キャッシュ、バックグラウンドワーカー、リバースプロキシなどのサービスをオーケストレーションできます。エージェントは開発環境と本番環境の両方の構成を理解し、Docker のベストプラクティスに従った Compose ファイルを生成できます。

ワークフロー

  1. アプリケーションスタックを分析する: エージェントはプロジェクトのアーキテクチャを確認し、必要なサービスとその依存関係を特定します。これには、主要なアプリケーションコンテナー、データベース(PostgreSQL、MySQL、MongoDB)、キャッシュ(Redis、Memcached)、メッセージキュー(RabbitMQ、Kafka)、バックグラウンドワーカー、リバースプロキシ(Nginx、Traefik)が含まれます。エージェントはサービス間の依存関係を整理し、起動順序とヘルスチェックの要件を判断します。

  2. サービスとイメージを定義する: エージェントは各サービスについて、Docker イメージまたはビルドコンテキスト、公開ポート、環境変数、リソース制約を指定します。アプリケーションサービスでは通常、ローカルの Dockerfile を指す build ディレクティブを使用します。一方、インフラストラクチャサービスでは、バージョンタグを固定した公式イメージを使用します。エージェントは、デプロイを再現可能にするため、本番環境で latest タグを使用しません。

  3. ネットワークとサービスディスカバリーを構成する: エージェントは名前付き Docker ネットワークを作成し、サービス層間のトラフィックを分離します(例:プロキシとアプリ用の frontend ネットワーク、アプリとデータベース用の backend ネットワーク)。サービスは Compose のサービス名を DNS ホスト名として使って通信するため、IP アドレスをハードコードする必要がありません。

  4. ボリュームと永続化を設定する: エージェントは、データベースストレージやファイルアップロードなど、コンテナーの再起動後も保持する必要のあるデータに名前付きボリュームを定義します。開発環境では、バインドマウントによってホストのソースコードをコンテナーにマッピングし、ホットリロードを可能にします。エージェントは、コンテナーの実行ユーザーに対して、ボリュームの権限と所有者が正しく設定されていることを確認します。

  5. ヘルスチェックと依存関係に基づく起動順序を設定する: エージェントは重要なサービスにヘルスチェックを設定し、依存するサービスが、単に起動しただけでなく、依存先が実際に準備できるまで待機するようにします。これにより、データベースは起動していても接続を受け付けていないためにアプリケーションコンテナーがクラッシュするといった、よくある問題を防ぎます。condition: service_healthy を指定した depends_on ディレクティブにより、正しい起動順序を確保します。

  6. 環境ごとのオーバーライドを作成する: エージェントは、共通設定用のベース docker-compose.yml と、環境ごとに設定をカスタマイズするオーバーライドファイル(開発環境用の docker-compose.override.yml、本番環境用の docker-compose.prod.yml)を生成します。開発環境用のオーバーライドにはバインドマウント、デバッグポート、詳細なログ出力を含め、本番環境用のオーバーライドにはリソース制限、再起動ポリシー、最適化されたログドライバーを含めます。

対応技術

  • Compose のバージョン: Docker Compose V2(Docker CLI プラグインに統合)
  • アプリケーションランタイム: Node.js、Python、Ruby、Go、Java、PHP、.NET
  • データベース: PostgreSQL、MySQL、MariaDB、MongoDB、Redis、Elasticsearch
  • リバースプロキシ: Nginx、Traefik、Caddy、HAProxy
  • メッセージキュー: RabbitMQ、Kafka、NATS
  • モニタリング: Prometheus、Grafana、cAdvisor

使用方法

必要なサービス、その関係、開発環境用か本番環境用かを含め、アプリケーションスタックの説明をエージェントに提示してください。

プロンプトの例:

Create a docker-compose setup for my Node.js app with:
- PostgreSQL database with persistent storage
- Redis for session caching
- Nginx reverse proxy with SSL termination
- A Celery-like background worker process
- Development setup with hot reloading

例

例 1:フルスタック Web アプリケーション(Node.js + PostgreSQL + Redis + Nginx)
services:
  nginx:
    image: nginx:1.25-alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
      - ./nginx/certs:/etc/nginx/certs:ro
    depends_on:
      app:
        condition: service_healthy
    networks:
      - frontend
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost/health"]
      interval: 30s
      timeout: 5s
      retries: 3

  app:
    build:
      context: .
      dockerfile: Dockerfile
    environment:
      NODE_ENV: production
      DATABASE_URL: postgres://appuser:${DB_PASSWORD}@postgres:5432/myapp
      REDIS_URL: redis://redis:6379
      SESSION_SECRET: ${SESSION_SECRET}
    depends_on:
      postgres:
        condition: service_healthy
      redis:
        condition: service_healthy
    networks:
      - frontend
      - backend
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "node", "-e", "fetch('http://localhost:3000/health').then(r => r.ok ? process.exit(0) : process.exit(1))"]
      interval: 15s
      timeout: 5s
      retries: 3
      start_period: 30s

  worker:
    build:
      context: .
      dockerfile: Dockerfile
    command: node worker.js
    environment:
      DATABASE_URL: postgres://appuser:${DB_PASSWORD}@postgres:5432/myapp
      REDIS_URL: redis://redis:6379
    depends_on:
      postgres:
        condition: service_healthy
      redis:
        condition: service_healthy
    networks:
      - backend
    restart: unless-stopped

  postgres:
    image: postgres:16-alpine
    environment:
      POSTGRES_DB: myapp
      POSTGRES_USER: appuser
      POSTGRES_PASSWORD: ${DB_PASSWORD}
    volumes:
      - postgres_data:/var/lib/postgresql/data
      - ./init.sql:/docker-entrypoint-initdb.d/init.sql:ro
    networks:
      - backend
    restart: unless-stopped
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U appuser -d myapp"]
      interval: 10s
      timeout: 5s
      retries: 5

  redis:
    image: redis:7-alpine
    command: redis-server --appendonly yes --maxmemory 256mb --maxmemory-policy allkeys-lru
    volumes:
      - redis_data:/data
    networks:
      - backend
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 3s
      retries: 3

volumes:
  postgres_data:
  redis_data:

networks:
  frontend:
  backend:
例 2:開発環境と本番環境のオーバーライド

docker-compose.yml(ベース、共有設定):

services:
  app:
    build:
      context: .
      dockerfile: Dockerfile
    environment:
      DATABASE_URL: postgres://appuser:${DB_PASSWORD}@postgres:5432/myapp
      REDIS_URL: redis://redis:6379
    depends_on:
      postgres:
        condition: service_healthy
    networks:
      - backend

  postgres:
    image: postgres:16-alpine
    environment:
      POSTGRES_DB: myapp
      POSTGRES_USER: appuser
      POSTGRES_PASSWORD: ${DB_PASSWORD}
    volumes:
      - postgres_data:/var/lib/postgresql/data
    networks:
      - backend
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U appuser -d myapp"]
      interval: 10s
      timeout: 5s
      retries: 5

volumes:
  postgres_data:

networks:
  backend:

docker-compose.override.yml(開発環境 — 自動的に読み込まれます):

services:
  app:
    build:
      target: development
    ports:
      - "3000:3000"
      - "9229:9229"   # Node.js debug port
    volumes:
      - .:/app
      - /app/node_modules
    environment:
      NODE_ENV: development
      DEBUG: "app:*"
    command: npm run dev

  postgres:
    ports:
      - "5432:5432"   # Expose DB to host for local tooling

docker-compose.prod.yml(本番環境 — -f と併用します):

services:
  app:
    build:
      target: production
    restart: unless-stopped
    environment:
      NODE_ENV: production
    deploy:
      resources:
        limits:
          cpus: "1.0"
          memory: 512M
        reservations:
          cpus: "0.5"
          memory: 256M
    logging:
      driver: json-file
      options:
        max-size: "10m"
        max-file: "3"

  postgres:
    restart: unless-stopped
    deploy:
      resources:
        limits:
          cpus: "2.0"
          memory: 1G

本番環境で実行するには、次のコマンドを使います:docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d

ベストプラクティス

  • 永続データには名前付きボリュームを使用する: データベースやアップロードファイルには、コンテナ内部のストレージを決して使用しないでください。名前付きボリュームはコンテナを再作成しても保持され、個別にバックアップできます。
  • イメージのバージョンを固定する: イメージの更新による予期しない破壊的変更を避けるため、latest ではなく、明示的なイメージタグ(例:postgres:16-alpine)を必ず指定してください。
  • すべてのサービスにヘルスチェックを設定する: ヘルスチェックにより、Docker は異常なコンテナを検出でき、condition: service_healthy を指定した depends_on によって、信頼性の高い起動順序を実現できます。ヘルスチェックがないと、依存先の準備が整う前に依存するサービスが起動する場合があります。
  • シークレットには .env ファイルを使用する: データベースのパスワードや API キーなどの機密情報は、.gitignore を使ってバージョン管理から除外した .env ファイルに保存してください。Compose ファイルでは ${VARIABLE} の構文で変数を参照します。
  • 階層ごとにネットワークを分ける: 通信を分離するために、異なるネットワークを使用してください。リバースプロキシからデータベースへ直接アクセスできないようにします。これにより、コンテナが侵害された場合の影響範囲を限定できます。
  • オーバーライドで Compose ファイルの重複を避ける: 環境ごとに Compose ファイル全体を複製するのではなく、ベースとオーバーライドのパターンを使用してください。これにより、共有するサービス定義の整合性を保てます。

エッジケース

  • ホスト上のポート競合: ホストのポートがすでに使用中の場合(例:別のサービスがポート 5432 を使用している場合)、Docker Compose はポートのバインドに失敗します。ホストポートを重複しないようにするか、Docker ネットワーク経由のコンテナ間通信だけが必要なサービスには ports: [] を設定してください。
  • ボリュームの権限不一致: 非 root ユーザーで実行されるコンテナは、ホスト側ディレクトリの権限が制限されていると、マウントされたボリュームへの書き込みに失敗する場合があります。Compose ファイルの user: ディレクティブを使用するか、Dockerfile のエントリーポイントで chown を実行して UID/GID を合わせてください。
  • ビルドキャッシュの無効化: Dockerfile の前半にある COPY または ADD 命令を変更すると、それ以降のすべてのレイヤーのキャッシュが無効になります。キャッシュを最大限再利用できるよう、Dockerfile の命令は変更頻度の低いものから高いものへと並べてください(依存関係をソースコードより前に配置します)。
  • 起動中のコンテナ DNS 解決: 依存先のコンテナに IP アドレスが割り当てられる前に、サービスがその DNS 名を解決しようとして、接続に失敗する場合があります。depends_on の条件付きヘルスチェックでこれを防げますが、アプリケーションレベルでの再試行ロジックも推奨されます。
  • 孤立したコンテナとボリューム: Compose ファイルからサービスを削除した後に docker compose up を実行すると、孤立したコンテナが起動したままになります。docker compose up --remove-orphans を使用し、定期的に docker volume prune を実行して、未使用のボリュームをクリーンアップしてください。

コメント