Communitygithub.com

docker-patterns

Docker および Docker Compose のベストパターン集。ローカル開発、セキュリティ強化、ネットワーク構成、ボリューム戦略、マルチサービスオーケストレーションをサポート。

docker-patterns とは?

このスキルは、Docker と Docker Compose に関する実用的なパターンとベストプラクティスを提供します。特に、Web アプリケーションのローカル開発環境の構築、セキュリティを考慮したコンテナ設計、ネットワークの分離、ボリュームの適切な管理、そしてハードニングされた CLI インストーラーのテストハーネス設計に焦点を当てています。Dockerfile のマルチステージビルドや Compose のオーバーライドファイル、Secret 管理、capability 制限、非 root 実行などの具体的な設定例が豊富に含まれており、開発から本番運用まで一貫したプラクティスを学べます。また、独自の CLI ツール (ecc) のインストーラーをテストするための隔離されたコンテナ環境の構築手順も詳細に記述されており、Linux ディストリビューションごとの検証や、macOS/Windows ネイティブ環境との違いを考慮したテスト戦略を示しています。このスキルは、Claude Code や Cursor などの AI エージェントが Dockerfile や Compose ファイルを作成・レビューする際、またはマルチプラットフォーム対応のインストーラーテストを計画する際に特に有用です。

対応✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/affaan-m/ECC/tree/main/skills/docker-patterns

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

Docker Patterns

コンテナ化開発のための Docker と Docker Compose のベストプラクティス。

ローカル開発向け Docker Compose

標準的な Web アプリケーションスタック

# docker-compose.yml
services:
  app:
    build:
      context: .
      target: dev                     # マルチステージ Dockerfile の dev ステージを使用
    ports:
      - "3000:3000"
    volumes:
      - .:/app                        # ホットリロード用のバインドマウント
      - /app/node_modules             # 匿名ボリューム -- コンテナの依存関係を保持
    environment:
      - DATABASE_URL=postgres://postgres:postgres@db:5432/app_dev
      - REDIS_URL=redis://redis:6379/0
      - NODE_ENV=development
    depends_on:
      db:
        condition: service_healthy
      redis:
        condition: service_started
    command: npm run dev

  db:
    image: postgres:16-alpine
    ports:
      - "5432:5432"
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: postgres
      POSTGRES_DB: app_dev
    volumes:
      - pgdata:/var/lib/postgresql/data
      - ./scripts/init-db.sql:/docker-entrypoint-initdb.d/init.sql
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 5s
      timeout: 3s
      retries: 5

  redis:
    image: redis:7-alpine
    ports:
      - "6379:6379"
    volumes:
      - redisdata:/data

  mailpit:                            # ローカルメールテスト
    image: axllent/mailpit
    ports:
      - "8025:8025"                   # Web UI
      - "1025:1025"                   # SMTP

volumes:
  pgdata:
  redisdata:

開発用と本番用の Dockerfile

# Stage: dependencies
FROM node:22-alpine AS deps
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci

# Stage: dev (ホットリロード、デバッグツール)
FROM node:22-alpine AS dev
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
EXPOSE 3000
CMD ["npm", "run", "dev"]

# Stage: build
FROM node:22-alpine AS build
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npm run build && npm prune --production

# Stage: production (最小イメージ)
FROM node:22-alpine AS production
WORKDIR /app
RUN addgroup -g 1001 -S appgroup && adduser -S appuser -u 1001
USER appuser
COPY --from=build --chown=appuser:appgroup /app/dist ./dist
COPY --from=build --chown=appuser:appgroup /app/node_modules ./node_modules
COPY --from=build --chown=appuser:appgroup /app/package.json ./
ENV NODE_ENV=production
EXPOSE 3000
HEALTHCHECK --interval=30s --timeout=3s CMD wget -qO- http://localhost:3000/health || exit 1
CMD ["node", "dist/server.js"]

オーバーライドファイル

# docker-compose.override.yml (自動読み込み、開発専用設定)
services:
  app:
    environment:
      - DEBUG=app:*
      - LOG_LEVEL=debug
    ports:
      - "9229:9229"                   # Node.js デバッガ

# docker-compose.prod.yml (本番用に明示的に指定)
services:
  app:
    build:
      target: production
    restart: always
    deploy:
      resources:
        limits:
          cpus: "1.0"
          memory: 512M
# 開発 (オーバーライドを自動読み込み)
docker compose up

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

ネットワーク

サービスディスカバリ

同じ Compose ネットワーク内のサービスは、サービス名で解決されます:

# "app" コンテナから:
postgres://postgres:postgres@db:5432/app_dev    # "db" は db コンテナに解決
redis://redis:6379/0                             # "redis" は redis コンテナに解決

カスタムネットワーク

services:
  frontend:
    networks:
      - frontend-net

  api:
    networks:
      - frontend-net
      - backend-net

  db:
    networks:
      - backend-net              # api からのみ到達可能、frontend からは不可

networks:
  frontend-net:
  backend-net:

必要なものだけを公開

services:
  db:
    ports:
      - "127.0.0.1:5432:5432"   # ホストからのみアクセス可能、ネットワークからは不可
    # 本番では ports を完全に省略 -- Docker ネットワーク内でのみアクセス可能

ボリューム戦略

volumes:
  # 名前付きボリューム: コンテナ再起動後も永続化、Docker が管理
  pgdata:

  # バインドマウント: ホストディレクトリをコンテナにマッピング (開発用)
  # - ./src:/app/src

  # 匿名ボリューム: バインドマウントの上書きからコンテナ生成コンテンツを保護
  # - /app/node_modules

一般的なパターン

services:
  app:
    volumes:
      - .:/app                   # ソースコード (ホットリロード用バインドマウント)
      - /app/node_modules        # コンテナの node_modules をホストから保護
      - /app/.next               # ビルドキャッシュを保護

  db:
    volumes:
      - pgdata:/var/lib/postgresql/data          # 永続データ
      - ./scripts/init.sql:/docker-entrypoint-initdb.d/init.sql  # 初期化スクリプト

コンテナセキュリティ

Dockerfile のハードニング

# 1. 特定のタグを使用する (:latest は避ける)
FROM node:22.12-alpine3.20

# 2. 非 root で実行
RUN addgroup -g 1001 -S app && adduser -S app -u 1001
USER app

# 3. ケーパビリティを削除 (compose で)
# 4. 可能な限り読み取り専用ルートファイルシステム
# 5. イメージレイヤーにシークレットを含めない

Compose のセキュリティ

services:
  app:
    security_opt:
      - no-new-privileges:true
    read_only: true
    tmpfs:
      - /tmp
      - /app/.cache
    cap_drop:
      - ALL
    cap_add:
      - NET_BIND_SERVICE          # ポート < 1024 にバインドする場合のみ必要

シークレット管理

# GOOD: 環境変数を使用 (実行時に注入)
services:
  app:
    env_file:
      - .env                     # .env は git にコミットしない
    environment:
      - API_KEY                  # ホスト環境から継承

# GOOD: Docker シークレット (Swarm モード)
secrets:
  db_password:
    file: ./secrets/db_password.txt

services:
  db:
    secrets:
      - db_password

# BAD: イメージにハードコード
# ENV API_KEY=sk-proj-xxxxx      # 絶対にしないでください

ハードニングされた CLI インストーラーハーネス

コンテナを使用して、ソースチェックアウトを変更せずに、使い捨てのプロジェクトコピーに対してインストーラーの動作をテストします。

プラットフォームの境界を尊重する

  • Debian や Ubuntu などの Linux ディストリビューションには実際のコンテナを実行します。
  • macOS は Docker が Linux カーネルを共有するため、Docker コンテナとして実行できません。同じシェルフリーのテストエントリポイントを macOS 上でネイティブに実行します。
  • Windows コンテナには Windows Docker エンジンが必要です。プラットフォームに依存しないロジックはネイティブの Windows CI ランナーで実行し、Windows コンテナは Windows ホスト用に予約します。
  • ホスト固有のパス、コマンドラッパー、引用符、ファイルシステムの動作をテストするために、ネイティブの Ubuntu/macOS/Windows CI マトリックスを維持します。

Linux コンテナが macOS や Windows の動作を検証すると主張しないでください。

分離契約を強制する

  • ベースイメージは不変のダイジェストで固定し、インストールする CLI バージョンも固定します。
  • ディストリビューションごとにアカウント名が異なる場合に備え、非 root の数値 UID/GID で実行します。
  • リポジトリとソースプロジェクトは読み取り専用でマウントします。
  • 変更を加える前に、ソースプロジェクトを書き込み可能な tmpfs ワークスペースにコピーします。
  • /workspace は noexec、UID/GID 1000、mode=0700 でマウントし、コンテナユーザーのみがプロジェクトデータを検査できるようにします。
  • npm と npx の実行可能キャッシュは NPM_CONFIG_CACHE=/tmp/npm-cache に、実行可能な /tmp マウント上に保持します。デフォルトサイズは 2 GiB で、ECC_TMPFS_SIZE で調整可能です。ECC_WORKSPACE_SIZE はプライベートワークスペースマウントを個別に制御します。
  • read_only: true、no-new-privileges:true、cap_drop: [ALL]、および有限の pids_limit を設定します。
  • デフォルトの実際の CLI サービスは network_mode: none に保ちます。ネットワークアクセスは、認証済みプロバイダーセッション用の名前付きオプトインサービスでのみ、明示的に追加します。偶発的な環境依存のデフォルトにしてはいけません。
  • ツールが必要とする書き込み可能な一時パスのみを作成します。
  • デフォルトでは、ホストの認証情報をコンテナに渡さないでください。
  • デフォルトは dry-run とし、明示的な dry-run、install、plugin、shell モードのみを許可します。
  • クロスプラットフォームランナーには、引数配列または spawnSync(..., { shell: false }) を使用します。プロジェクトパスをシェルコマンドに展開しないでください。

ECC プラグインセットアップハーネスを実行する

docker/plugin-setup/compose.yaml をリファレンス実装として使用します。以下を提供します:

  • fixture-tests:フォーカスされたインストールマニフェスト、ターゲット、およびエグゼキュータスイート用。
  • real-cli:固定された Debian ベースの汎用 Linux イメージ用。
  • real-cli-ubuntu:固定された Ubuntu イメージ用。

ビルド前に Compose モデルを検証します:

docker compose -f docker/plugin-setup/compose.yaml config --quiet

両方の実際の Linux イメージをビルドします:

docker compose -f docker/plugin-setup/compose.yaml \
  build real-cli real-cli-ubuntu

各イメージで安全なデフォルトフローを実行します:

docker compose -p ecc-plugin-debian-test \
  -f docker/plugin-setup/compose.yaml \
  run --rm -T real-cli dry-run

docker compose -p ecc-plugin-ubuntu-test \
  -f docker/plugin-setup/compose.yaml \
  run --rm -T real-cli-ubuntu dry-run

ドライランは現在のパブリックコマンド契約を実行します:

ecc install --profile core --target claude-project --dry-run --json

そのコマンドが実行される前に、コンテナは読み取り専用チェックアウトから npm pack --ignore-scripts でローカルにパッケージ化された npm アーティファクトを作成します。自己生成した tarball を /tmp の下に展開し、ecc-universal パッケージ名、必要なインストールマニフェスト、制限された package.json の bin.ecc マッピングを検証し、展開された ecc 実行可能ファイルを呼び出します。ランタイムは network_mode: none のままで、パッケージライフサイクルスクリプトを実行せず、ホストの node_modules に依存しません。その正確に固定された本番依存関係はすでにイメージに含まれています。

ハーネスは、空のプラン、claude-project 以外のターゲット、/workspace/project/.claude 外の操作、またはターゲットディレクトリを作成するドライランを拒否します。install は隔離された適用を2回実行し、管理されたインストール状態をチェックし、インストールされたターゲットを一覧表示し、doctor を実行します。

名前付きセッションの開始、開く、再接続、およびクリーンアップ

--rm なしでデタッチドコンテナを開始し、ターミナルを離れてもセッションが削除されないようにします:

docker compose -p ecc-plugin-session \
  -f docker/plugin-setup/compose.yaml \
  run --detach --name ecc-plugin-shell real-cli shell

コンテナは読み取り専用フィクスチャを安定したプライベートディレクトリ /workspace/project にコピーします。実行中であることを確認し、ターミナルオープナー v1 データ契約の Docker 側を出力します:

docker inspect --format '{{.State.Running}}' ecc-plugin-shell
node docker/plugin-setup/interactive-plan.js \
  --container ecc-plugin-shell \
  --workdir /workspace/project \
  --json \
  -- bash

JSON 結果には、正確に executable と argv の境界(および contractVersion: 1)が含まれます:実行可能ファイルは docker で、argv は exec、-it、-w で始まります。そのデータを、ターミナルオープナースキルがインストールされている場合は、別のターミナルオープナースキルに渡します。この Docker ハーネスは、ターミナルアダプターのインポート、シェルコマンドの展開、またはホスト GUI プロセスの管理を意図的に行いません。それまでは、現在のホストターミナルで同じ PTY を直接開きます:

docker exec -it -w /workspace/project ecc-plugin-shell bash

デタッチドコンテナを停止せずにシェルを終了します。同じ docker exec -it コマンドで再接続します。完了したら、正確な名前付きコンテナとその Compose プロジェクトリソースを削除します:

docker rm --force ecc-plugin-shell
docker compose -p ecc-plugin-session \
  -f docker/plugin-setup/compose.yaml \
  down --remove-orphans

ホスト認証情報はデフォルトでは存在せず、認証情報ディレクトリはマウントされません。デフォルトのサービスはネットワークアクセスもありません。認証済みプロバイダーセッションが本当にネットワークを必要とする場合は、最初に real-cli をビルドし、docker compose --profile networked run real-cli-networked shell で明示的にオプトインします。その使い捨てセッション内で認証することを推奨します。CI 実行がホスト環境の認証情報を継承する必要がある場合は、呼び出し時に明示的な Compose --env NAME フラグでオプトインし、その値が検査可能でコンテナの存続期間中に流出する可能性があることを理解し、正確な名前付きコンテナをすぐに削除します。

同じフォーカスされたスイートをホスト上でネイティブに実行します:

npm run test:plugin-setup-platform

イメージを信頼する前に、生成された ID と環境を検査します:

docker image inspect ecc-plugin-setup:debian ecc-plugin-setup:ubuntu

関連のないボリュームやイメージを削除せずに、各名前付きテストプロジェクトをクリーンアップします:

docker compose -p ecc-plugin-debian-test \
  -f docker/plugin-setup/compose.yaml down --remove-orphans
docker compose -p ecc-plugin-ubuntu-test \
  -f docker/plugin-setup/compose.yaml down --remove-orphans

.dockerignore

node_modules
.git
.env
.env.*
dist
coverage
*.log
.next
.cache
docker-compose*.yml
Dockerfile*
README.md
tests/

デバッグ

一般的なコマンド

# ログを表示
docker compose logs -f app           # app のログを追跡
docker compose logs --tail=50 db     # db の最新50行

# 実行中のコンテナでコマンドを実行
docker compose exec app sh           # app にシェルで入る
docker compose exec db psql -U postgres  # postgres に接続

# 検査
docker compose ps                     # 実行中のサービス
docker compose top                    # 各コンテナのプロセス
docker stats                          # リソース使用量

# リビルド
docker compose up --build             # イメージを再ビルド
docker compose build --no-cache app   # 完全リビルドを強制

# クリーンアップ
docker compose down                   # コンテナを停止して削除
docker compose down -v                # ボリュームも削除 (破壊的)
docker system prune                   # 未使用イメージ/コンテナを削除

ネットワーク問題のデバッグ

# コンテナ内の DNS 解決を確認
docker compose exec app nslookup db

# 接続性を確認
docker compose exec app wget -qO- http://api:3000/health

# ネットワークを検査
docker network ls
docker network inspect <project>_default

アンチパターン

# BAD: 最新のイメージタグを使用
FROM node:latest

# BAD: ルートで実行
USER root

# BAD: イメージにシークレットをハードコード
ENV API_KEY=sk-proj-xxxxx

# BAD: ビルドコンテキストに .env を含める
# (.dockerignore に追加すること)

# BAD: 依存関係の順序を正しく設定しない
# depends_on に condition: service_healthy を使用せず、サービスが準備できる前に接続しようとする

# BAD: 本番 Compose ファイルに開発ボリュームを残す
services:
  app:
    volumes:
      - .:/app   # 本番では絶対にしないでください

参考資料

Individual skills in this repo

This repo contains 20 individual skills — each has its own dedicated page.

accessibility

Design, implement, and audit inclusive digital products using WCAG 2.2 Level AA. Use when building or auditing UI that must meet WCAG 2.2 Level AA, or when reviewing a change for keyboard, contrast, or screen-reader support.

affaan-m/content-engine

Create platform-native content systems for X, LinkedIn, TikTok, YouTube, newsletters, and repurposed multi-platform campaigns. Use when the user wants social posts, threads, scripts, content calendars, or one source asset adapted cleanly across platforms.

affaan-m/ECC

Multi-platform content distribution across X, LinkedIn, Threads, and Bluesky. Adapts content per platform using content-engine patterns. Never posts identical content cross-platform. Use when the user wants to distribute content across social platforms.

affaan-m/fal-ai-media

Unified media generation via fal.ai MCP — image, video, and audio. Covers text-to-image (Nano Banana), text/image-to-video (Seedance, Kling, Veo 3), text-to-speech (CSM-1B), and video-to-audio (ThinkSound). Use when the user wants to generate images, videos, or audio with AI.

affaan-m/manim-video

日本語翻訳:このファイルは manim-video 用の日本語翻訳が必要です

affaan-m/remotion-video-creation

Remotion のベストプラクティス - React で動画を作成する。3D、アニメーション、音声、字幕、チャート、トランジションなどをカバーするドメイン固有の29のルール。

affaan-m/video-editing

AI-assisted video editing workflows for cutting, structuring, and augmenting real footage. Covers the full pipeline from raw capture through FFmpeg, Remotion, ElevenLabs, fal.ai, and final polish in Descript or CapCut. Use when the user wants to edit video, cut footage, create vlogs, or build video content.

agent-architecture-audit

Full-stack diagnostic for agent and LLM applications. Audits the 12-layer agent stack for wrapper regression, memory pollution, tool discipline failures, hidden repair loops, and rendering corruption. Produces severity-ranked findings with code-first fixes. Essential for developers building agent applications, autonomous loops, or any LLM-powered feature. Use when an agent or LLM feature misbehaves and the failing layer is unknown, or before shipping an agent stack.

agent-eval

Head-to-head comparison of coding agents (Claude Code, Aider, Codex, etc.) on custom tasks with pass rate, cost, time, and consistency metrics. Use when choosing between coding agents, or when a change to an agent setup needs measured pass rate, cost, and time rather than an impression.

agent-harness-construction

Design and optimize AI agent action spaces, tool definitions, and observation formatting for higher completion rates. Use when defining or revising an agent

agentic-engineering

Operate as an agentic engineer using eval-first execution, decomposition, and cost-aware model routing. Use when planning or executing engineering work that agents will carry out end to end.

agentic-os

Build persistent multi-agent operating systems on Claude Code. Covers kernel architecture, specialist agents, slash commands, file-based memory, scheduled automation, and state management without external databases. Use when building a persistent multi-agent system on Claude Code with its own memory, commands, and scheduling.

agent-introspection-debugging

Structured self-debugging workflow for AI agent failures using capture, diagnosis, contained recovery, and introspection reports. Use when an agent run fails and you need a reproducible diagnosis instead of a retry.

agent-payment-x402

Add x402 payment execution to AI agents with per-task budgets, spending controls, and non-custodial wallets. Supports Base through agentwallet-sdk and X Layer through OKX Payments / OKX Agent Payments Protocol. Use when an agent must pay for something itself and needs per-task budgets, spending controls, and a non-custodial wallet.

agent-self-evaluation

Use after completing any non-trivial task. The agent self-rates its output on 5 axes — accuracy, completeness, clarity, actionability, conciseness — with concrete evidence per criterion. Produces a structured 1-5 scorecard with specific improvement suggestions.

agent-sort

Build an evidence-backed ECC install plan for a specific repo by sorting skills, commands, rules, hooks, and extras into DAILY vs LIBRARY buckets using parallel repo-aware review passes. Use when ECC should be trimmed to what a project actually needs instead of loading the full bundle.

ai-first-engineering

Engineering operating model for teams where AI agents generate a large share of implementation output. Use when setting team process, review gates, or ownership rules for a codebase largely written by agents.

ai-regression-testing

Regression testing strategies for AI-assisted development. Sandbox-mode API testing without database dependencies, automated bug-check workflows, and patterns to catch AI blind spots where the same model writes and reviews code. Use when adding regression coverage to AI-assisted code, or when the same model both wrote and reviewed a change.

android-clean-architecture

Clean Architecture patterns for Android and Kotlin Multiplatform projects — module structure, dependency rules, UseCases, Repositories, and data layer patterns. Use when structuring modules, layers, or data flow in an Android or KMP project.

angular-developer

Generates Angular code and provides architectural guidance. Trigger when creating projects, components, or services, or for best practices on reactivity (signals, linkedSignal, resource), forms, dependency injection, routing, SSR, accessibility (ARIA), animations, styling (component styles, Tailwind CSS), testing, or CLI tooling.

関連スキル