Communitygithub.com

docker-patterns

Docker および Docker Compose を使用したローカル開発、安全なCLIインストーラーのテストハーネス、コンテナセキュリティ、ネットワーキング、ボリューム、マルチサービスオーケストレーションのパターン集。DockerfileやComposeサービスの作成・レビュー時、Linuxディストリビューション間でのインストーラーテスト、正確なネイティブmacOS/Windows検証の計画時に利用します。

docker-patterns とは?

このスキルは、Docker と Docker Compose に関する包括的なベストプラクティスを提供し、ローカル開発環境のセットアップから本番デプロイ、さらには CLI インストーラーのテストハーネスまでをカバーします。Dockerfile のマルチステージビルド、コンテナセキュリティの強化(非root実行、ケーパビリティ制限、読み取り専用ファイルシステム)、ネットワーク分離、名前付きボリュームとバインドマウントの適切な使い分けなど、実践的なパターンを YAML および Dockerfile の具体例とともに示します。特に、Linux コンテナで macOS や Windows の動作を検証できないというプラットフォーム境界を尊重し、それぞれのネイティブ環境でのテストを推奨する点が重要です。スキルは、任意の Docker/Compose プロジェクトの作成やレビュー、CI/CD パイプラインでのインストーラーテストに直接活用できます。

対応✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/affaan-m/everything-claude-code/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からのみ

networks:
  frontend-net:
  backend-net:

必要なものだけを公開

services:
  db:
    ports:
      - "127.0.0.1:5432:5432"   # ホストからのみアクセス可能、ネットワークからは不可
    # 本番ではポートを完全に省略 -- 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カーネルを共有するため、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 の実行可能キャッシュを、実行可能な /tmp マウント上の NPM_CONFIG_CACHE=/tmp/npm-cache に保持します。デフォルトサイズは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、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 にコピーします。実行中であることを確認し、ターミナルオープナーのDocker側v1データコントラクトを出力します:

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: 使用してはいけないパターン
# 1. :latest タグの使用
# 2. ルートユーザーでの実行
# 3. シークレットのイメージへのハードコード
# 4. バインドマウントの過剰な使用(本番)
# 5. ヘルスチェックの欠如
# 6. 依存関係の順序制御の欠如(depends_on: condition なし)
# 7. 巨大なイメージ(マルチステージビルドを使用しない)
# 8. ホストネットワークモードの使用

コンテナイメージのベストプラクティス

  • 最小限のベースイメージを使用(alpine、distroless)
  • マルチステージビルドを活用してイメージサイズを削減
  • すべてのレイヤーをラベル付けし、イメージにラベルを追加
  • 定期的にイメージをスキャンして脆弱性をチェック
  • 不変のタグ(SHA256ダイジェスト)を使用して再現性を確保
  • HEALTHCHECK命令を含める
  • 機密情報がレイヤーに残らないように注意

リソース制限と監視

services:
  app:
    deploy:
      resources:
        limits:
          cpus: "0.5"
          memory: 256M
        reservations:
          cpus: "0.25"
          memory: 128M
    # docker compose 以外の場合:
    # cpus: "0.5"
    # mem_limit: 256m

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/claude-api

Anthropic Claude API patterns for Python and TypeScript. Covers Messages API, streaming, tool use, vision, extended thinking, batches, prompt caching, and Claude Agent SDK. Use when building applications with the Claude API or Anthropic SDKs.

affaan-m/everything-claude-code

End-to-end marketing campaign planning and execution. Covers audience research, positioning, campaign angle definition, landing page copy, email sequences, social posts, ad copy, short-form video scripts, and content calendars. Use as the orchestration layer for multi-channel product launches. Use when planning or executing a multi-channel product launch, or producing landing page, email, social, or ad copy.

affaan-m/everything-claude-code

Development conventions and patterns for everything-claude-code. JavaScript project with conventional commits.

affaan-m/everything-claude-code-conventions

Development conventions and patterns for everything-claude-code. JavaScript project with conventional commits.

affaan-m/frontend-design

Create distinctive, production-grade frontend interfaces with high design quality. Use when the user asks to build web components, pages, or applications and the visual direction matters as much as the code quality.

affaan-m/gget

gget CLI and Python workflow for quick genomic database queries, sequence lookup, BLAST-style searches, enrichment checks, and reproducible bioinformatics evidence logs.

affaan-m/literature-review

Systematic literature-review workflow for academic, biomedical, technical, and scientific topics, including search planning, source screening, synthesis, citation checks, and evidence logging.

affaan-m/motion-ui

Production-ready UI motion system for React/Next.js. Use when implementing animations, transitions, or motion patterns.

affaan-m/project-guidelines-example

Example project-specific skill template based on a real production application.

affaan-m/pubmed-database

Direct PubMed and NCBI E-utilities search workflows for biomedical literature, MeSH queries, PMID lookup, citation retrieval, and API-backed literature monitoring.

affaan-m/scholar-evaluation

Structured scholarly-work evaluation for papers, proposals, literature reviews, methods sections, evidence quality, citation support, and research-writing feedback.

affaan-m/uspto-database

USPTO patent and trademark data workflow for official record lookup, PatentSearch queries, TSDR checks, assignment data, and reproducible IP research logs.

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.

関連スキル