docker-compose-setup について
Docker Compose を使ったマルチコンテナ構成の設計と設定を支援するスキルです。サービス依存関係、ネットワーク、永続ストレージ、ヘルスチェックに加え、開発環境と本番環境の設定分離を扱います。
主な機能
- 01サービスと依存関係を整理
- 02イメージ、ポート、変数を設定
- 03ネットワークとサービス検出を設定
- 04永続ボリュームとマウントを管理
- 05ヘルスチェックと起動順序を追加
- 06環境別のオーバーライドを作成
活用シーン
- 01複数サービスのアプリ構成を定義
- 02データベースやアップロードデータを永続化
- 03依存関係に応じてサービスを起動
- 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 ファイルを生成できます。
ワークフロー
-
アプリケーションスタックを分析する: エージェントはプロジェクトのアーキテクチャを確認し、必要なサービスとその依存関係を特定します。これには、主要なアプリケーションコンテナー、データベース(PostgreSQL、MySQL、MongoDB)、キャッシュ(Redis、Memcached)、メッセージキュー(RabbitMQ、Kafka)、バックグラウンドワーカー、リバースプロキシ(Nginx、Traefik)が含まれます。エージェントはサービス間の依存関係を整理し、起動順序とヘルスチェックの要件を判断します。
-
サービスとイメージを定義する: エージェントは各サービスについて、Docker イメージまたはビルドコンテキスト、公開ポート、環境変数、リソース制約を指定します。アプリケーションサービスでは通常、ローカルの Dockerfile を指す
buildディレクティブを使用します。一方、インフラストラクチャサービスでは、バージョンタグを固定した公式イメージを使用します。エージェントは、デプロイを再現可能にするため、本番環境でlatestタグを使用しません。 -
ネットワークとサービスディスカバリーを構成する: エージェントは名前付き Docker ネットワークを作成し、サービス層間のトラフィックを分離します(例:プロキシとアプリ用の
frontendネットワーク、アプリとデータベース用のbackendネットワーク)。サービスは Compose のサービス名を DNS ホスト名として使って通信するため、IP アドレスをハードコードする必要がありません。 -
ボリュームと永続化を設定する: エージェントは、データベースストレージやファイルアップロードなど、コンテナーの再起動後も保持する必要のあるデータに名前付きボリュームを定義します。開発環境では、バインドマウントによってホストのソースコードをコンテナーにマッピングし、ホットリロードを可能にします。エージェントは、コンテナーの実行ユーザーに対して、ボリュームの権限と所有者が正しく設定されていることを確認します。
-
ヘルスチェックと依存関係に基づく起動順序を設定する: エージェントは重要なサービスにヘルスチェックを設定し、依存するサービスが、単に起動しただけでなく、依存先が実際に準備できるまで待機するようにします。これにより、データベースは起動していても接続を受け付けていないためにアプリケーションコンテナーがクラッシュするといった、よくある問題を防ぎます。
condition: service_healthyを指定したdepends_onディレクティブにより、正しい起動順序を確保します。 -
環境ごとのオーバーライドを作成する: エージェントは、共通設定用のベース
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を実行して、未使用のボリュームをクリーンアップしてください。