Communitygithub.com

Docker 模式

Docker 與 Docker Compose 的開發、安全、網路及多服務編排模式。適用於撰寫或審查 Dockerfile 與 Compose 服務、測試跨 Linux 發行版的安裝程式,以及規劃精準的原生 macOS 與 Windows 驗證。

Docker 模式 是什麼?

這個技能提供一套全面的 Docker 與 Docker Compose 模式,涵蓋本地開發、容器安全、網路、磁碟區策略,以及一個強化過的 CLI 安裝程式測試框架。開發者可在多階段 Dockerfile 中區分開發與生產環境,透過 Compose override 檔案管理環境特定設定,並利用自訂網路與繫結掛載 (bind mount) 來最佳化工作流程。安全性方面強調執行非 root 使用者、捨棄權限 (drop capabilities)、使用唯讀根檔案系統,以及透過環境變數或 Docker secrets 安全地管理機密,完全避免在映像檔層中寫入硬編碼。此技能也深入說明如何利用隔離的 Docker 容器來測試 CLI 安裝程式實作,確保不會變異原始碼倉庫,並使用固定的映像檔摘要、唯讀掛載、tmpfs 工作區和嚴格的網路設定。同時明確指出平台邊界,例如 macOS 無法以 Docker 容器執行,必須在原生環境中進行測試,Windows 也需要專用的 Docker 引擎。支援在 Claude Code、Cursor 及 Codex 等工具中使用,以發展一致的容器化策略。

相容平台✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/affaan-m/everything-claude-code/tree/main/skills/docker-patterns

在你喜歡的 AI 中提問

開啟一個已預先載入此 Agent Skill 的新對話。

說明文件

Docker 模式 是做什麼的?

Docker 與 Docker Compose 的最佳實務,適用於容器化開發。

用於本地開發的 Docker Compose

標準網頁應用程式堆疊

# 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:

開發 vs 生產 Dockerfile

# 階段:相依套件
FROM node:22-alpine AS deps
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci

# 階段:開發(熱重載、除錯工具)
FROM node:22-alpine AS dev
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
EXPOSE 3000
CMD ["npm", "run", "dev"]

# 階段:建置
FROM node:22-alpine AS build
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npm run build && npm prune --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 的連接埠時需要

機密管理

# 良好作法:使用環境變數(執行時期注入)
services:
  app:
    env_file:
      - .env                     # 絕對不要將 .env 提交到 git
    environment:
      - API_KEY                  # 從主機環境繼承

# 良好作法:Docker secrets(Swarm 模式)
secrets:
  db_password:
    file: ./secrets/db_password.txt

services:
  db:
    secrets:
      - db_password

# 錯誤作法:在映像檔中硬編碼
# ENV API_KEY=sk-proj-xxxxx      # 絕對不要這麼做

強化過的 CLI 安裝程式測試框架

使用容器來測試安裝程式對可丟棄的專案副本的行為,而不允許測試變異原始碼倉庫。

尊重平台邊界

  • 針對 Linux 發行版(如 Debian 和 Ubuntu)執行真正的容器。
  • macOS 無法作為 Docker 容器執行,因為 Docker 共用一個 Linux 核心。請在 macOS 上原生執行相同的無 shell 測試進入點。
  • Windows 容器需要 Windows Docker 引擎。請在原生 Windows CI 執行器上執行與平台無關的邏輯,並保留 Windows 容器給 Windows 主機。
  • 保留原生的 Ubuntu / macOS / Windows CI 矩陣,以測試主機特定的路徑、命令 shim、引號處理和檔案系統行為。

請不要聲稱 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 }) 作為跨平台執行器。絕不要將專案路徑插入到 shell 命令中。

執行 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 會執行兩次隔離的套用,檢查其管理的安裝狀態,列出已安裝的目標,並執行 doctor。

啟動、開啟、重新連線和清理具名會話

啟動一個分離的容器,不要使用 --rm,這樣離開終端機時不會移除該會話:

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

該容器會將唯讀的 fixture 複製到穩定的私有目錄 /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 框架刻意不匯入終端機轉接器、不插入 shell 命令,也不管理主機 GUI 程序。在此之前,請直接在當前的主機終端機中開啟同一個 PTY:

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

退出 shell,不要停止分離的容器。使用相同的 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

在信任映像檔之前,檢查產生的身份和環境:

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 的 shell
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 <專案名稱>_default

反模式

# 錯誤作法:使用 latext
# FROM node:latest

# 錯誤作法:以 root 身分執行
# USER root

# 錯誤作法:在映像檔層中寫入機密
# ENV DB_PASSWORD=supersecret

# 錯誤作法:忽略 .dockerignore
# 這會將 node_modules 複製到建置上下文

# 錯誤作法:直接使用繫結掛載而沒有匿名磁碟區
# volumes:
#   - .:/app
# 缺少 /app/node_modules 會導致容器套件被主機的 node_modules 覆蓋

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.

相關技能