Use Cases (更新: 2026/6/3)

Claude Code 与 Docker 实战:Compose、Volume、Network 和 CI 构建

用 Claude Code 安全整理 Dockerfile、Compose、本地环境和 CI 镜像构建。

Claude Code 与 Docker 实战:Compose、Volume、Network 和 CI 构建

先决定要让 Claude Code 负责什么

只对 Claude Code 说“帮我 Docker 化”,很容易得到一个能跑一次、但难以审查的 Dockerfile。Docker 的核心是把应用运行环境打包起来:image 是模板,container 是运行中的实例,volume 把数据保存在容器外,network 让多个容器可以用服务名互相访问。

实际项目里,Dockerfile 只是其中一部分。还要一起看 docker-compose.yml.dockerignore、环境变量、health check 和 CI build。建议打开官方文档一起核对:Dockerfile referenceCompose file referenceDocker build best practicesDocker Build GitHub Actions 以及 Claude Code overview

如果你还要整理 CI,可以参考 Claude Code CI/CD setup。权限边界和安全审查可以接着看 Claude Code approval and sandbox guideClaude Code security best practices

4 个常见使用场景

Docker 集成的价值不是“看起来专业”,而是让团队少猜环境。先写清楚要解决的问题,再让 Claude Code 改文件。

场景Docker 固定的内容可以交给 Claude Code 的任务
新成员入门Node.js、PostgreSQL、Redis、端口、启动命令docker compose up 启动完整 stack
接近生产的调试环境变量、服务名、health check、启动顺序列出本地和生产差异
Pull Request 验证Dockerfile、lockfile、build cache、CI 日志增加只 build image 的 workflow
培训和交接命令、失败模式、恢复步骤把规则写入 CLAUDE.md 和 README

对有收入目标的 SaaS 或内容站来说,这很重要。结账、咨询表单、管理画面、产品页如果只在某台电脑上可用,收入就依赖不可复现的本地状态。个人学习可以从 ClaudeCodeLab 产品 开始;团队想把规则、权限、CI 和 review 流程落到真实仓库,可以看 Claude Code 培训与咨询

给 Claude Code 的安全提示词

第一次指示要包括目标、要生成的文件、禁止事项和验证方法。这样可以减少“看起来像 Docker 化了,但其实很危险”的输出。

Dockerize this Node.js + TypeScript API.

Context:
- pnpm is the package manager.
- The app listens on port 3000.
- GET /health returns 200.
- Local development needs PostgreSQL 16 and Redis 7.

Create:
- Production multi-stage Dockerfile
- docker-compose.yml for local development
- .dockerignore
- Docker-related package.json scripts
- GitHub Actions workflow that only verifies docker build

Constraints:
- Do not run the production container as root.
- Do not COPY .env files or secrets into the image.
- Explain the volume and network choices for the README.
- Include verification commands and how to inspect failures.

multi-stage build 的意思是把构建环境和运行环境分开。TypeScript 编译工具留在 build stage,最终 image 只带生产依赖和编译后的 dist。这会降低体积,也减少生产环境里的攻击面。

可复制的 Dockerfile

下面假设 API 把 src/index.ts 构建为 dist/index.jsdev stage 给本地 Compose 用,runner stage 给生产镜像用。

# syntax=docker/dockerfile:1

FROM node:22-bookworm-slim AS base
ENV PNPM_HOME="/pnpm"
ENV PATH="$PNPM_HOME:$PATH"
WORKDIR /app
RUN corepack enable

FROM base AS dev
ENV NODE_ENV=development
COPY package.json pnpm-lock.yaml ./
RUN pnpm install --frozen-lockfile
COPY . .
CMD ["pnpm", "dev"]

FROM base AS deps
COPY package.json pnpm-lock.yaml ./
RUN pnpm install --frozen-lockfile

FROM deps AS build
COPY tsconfig.json ./
COPY src ./src
RUN pnpm build

FROM base AS prod-deps
ENV NODE_ENV=production
COPY package.json pnpm-lock.yaml ./
RUN pnpm install --frozen-lockfile --prod && pnpm store prune

FROM base AS runner
ENV NODE_ENV=production
RUN groupadd --system --gid 1001 nodejs \
  && useradd --system --uid 1001 --gid nodejs appuser
COPY --from=prod-deps --chown=appuser:nodejs /app/node_modules ./node_modules
COPY --from=build --chown=appuser:nodejs /app/dist ./dist
COPY --chown=appuser:nodejs package.json ./
USER appuser
EXPOSE 3000
HEALTHCHECK --interval=30s --timeout=3s --retries=3 CMD node -e "fetch('http://127.0.0.1:3000/health').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))"
CMD ["node", "dist/index.js"]

让 Claude Code review 时,重点问三件事:secret 是否可能进入 image、COPY 顺序是否破坏 cache、runtime image 是否还残留 devDependencies。

Compose 中的 Volume 和 Network

Compose 可以一次启动多个容器。这里 API、PostgreSQL、Redis 在同一个 network 内,API 可以通过 postgresredis 这两个服务名连接。Volume 则让数据离开一次性容器:pgdata 保存数据库文件,api_node_modules 避免宿主机的 node_modules 覆盖 Linux 容器里的依赖。

services:
  api:
    build:
      context: .
      target: dev
    command: pnpm dev
    ports:
      - "3000:3000"
    environment:
      NODE_ENV: development
      DATABASE_URL: postgres://app:app@postgres:5432/app
      REDIS_URL: redis://redis:6379
    depends_on:
      postgres:
        condition: service_healthy
      redis:
        condition: service_healthy
    volumes:
      - .:/app
      - api_node_modules:/app/node_modules
    healthcheck:
      test: ["CMD", "node", "-e", "fetch('http://127.0.0.1:3000/health').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))"]
      interval: 10s
      timeout: 3s
      retries: 5

  postgres:
    image: postgres:16-alpine
    environment:
      POSTGRES_USER: app
      POSTGRES_PASSWORD: app
      POSTGRES_DB: app
    ports:
      - "5432:5432"
    volumes:
      - pgdata:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U app -d app"]
      interval: 5s
      timeout: 3s
      retries: 10

  redis:
    image: redis:7-alpine
    ports:
      - "6379:6379"
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 5s
      timeout: 3s
      retries: 10

volumes:
  pgdata:
  api_node_modules:

depends_on 主要控制启动顺序,不等于数据库已经可以连接。配合 healthcheckcondition: service_healthy,可以减少 API 抢跑导致的连接失败。

防止 secret 进入 build context

先写 .dockerignore。它可以减少 build context,也能挡住最危险的 .env

.git
node_modules
dist
coverage
.env
.env.*
!.env.example
npm-debug.log*
pnpm-debug.log*
Dockerfile*
docker-compose*.yml

再把团队常用命令放进 package.json。这样每个人都执行同一套命令,Claude Code 也能引用同一个检查入口。

{
  "scripts": {
    "dev": "tsx watch src/index.ts",
    "build": "tsc -p tsconfig.json",
    "start": "node dist/index.js",
    "docker:dev": "docker compose up --build",
    "docker:check": "bash scripts/docker-check.sh"
  },
  "dependencies": {
    "@fastify/redis": "latest",
    "fastify": "latest",
    "pg": "latest"
  },
  "devDependencies": {
    "tsx": "latest",
    "typescript": "latest"
  }
}

可重复的检查脚本

手动检查容易漏。把步骤放进 scripts/docker-check.sh,以后服务增加时再让 Claude Code 更新脚本。

#!/usr/bin/env bash
set -euo pipefail

docker compose build api
docker compose up -d postgres redis api

cleanup() {
  docker compose down
}
trap cleanup EXIT

for attempt in {1..30}; do
  if curl -fsS http://127.0.0.1:3000/health >/dev/null; then
    echo "healthcheck ok"
    exit 0
  fi
  echo "waiting for api... ${attempt}/30"
  sleep 2
done

docker compose logs api
exit 1

这段脚本会 build、启动 stack、等待 /health,失败时输出 API 日志。它比 README 里一串手动命令更可靠。

CI 先 build,不急着 push

第一步只验证 image 能不能 build,不向 registry 发布。等基础稳定后,再加入 push、签名、漏洞扫描和 SBOM。

name: docker-build

on:
  pull_request:
  push:
    branches:
      - main

jobs:
  image:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      packages: write
    steps:
      - uses: actions/checkout@v4
      - uses: docker/setup-buildx-action@v3
      - uses: docker/build-push-action@v7
        with:
          context: .
          target: runner
          push: false
          tags: claude-code-docker-sample:${{ github.sha }}
          cache-from: type=gha
          cache-to: type=gha,mode=max

让 Claude Code 解释这个 workflow 是否会 push、权限是否过大、cache 为空时是否仍能 build。它的回答应该能指向具体 YAML 行。

常见失败

第一类是把 .env 复制进 image。secret 一旦进入 registry,处理成本会很高。.dockerignore、CI secrets、build log 要一起看。

第二类是把宿主机的 node_modules 挂进 Linux 容器。macOS、Windows、Linux 的 native module 可能不同。命名 volume 可以隔离这件事。

第三类是 API 比数据库先启动。depends_on 不是万能保险,数据库 health check 和应用重试都要有。

第四类是生产容器使用 root。demo 里看不出问题,但真实服务会扩大风险。让 Claude Code 指出证明 non-root 的 Dockerfile 行,会比“看起来安全”更可审查。

安全工作流

推荐顺序是:读仓库、列 runtime 依赖、先写 .dockerignore、再写 Compose、再写生产 Dockerfile、再放验证脚本、最后加 CI。每一步结束后读 git diff,让 Claude Code 输出 changed files、reason、verification command、remaining risk。

这也适合 session handoff template。Docker 集成不该只是一次性生成文件,而应该变成团队共享的开发习惯。

初学者最容易误解的是“放进 Docker 就等于和生产一致”。本地 Compose 只能帮助统一启动顺序、环境变量、端口、Volume 和基础依赖,不能自动复现真实云环境的 CPU、内存、网络延迟、托管数据库、TLS、日志管道和权限策略。让 Claude Code 在 PR 里明确写出“本地已验证什么”和“本地无法证明什么”,可以避免把 demo 当成生产保证。

如果服务会影响付款、预约、邮件、广告计量或咨询表单,还要把业务路径加入 Docker 检查。容器能启动但转化事件丢失,依然是事故。先用假数据验证 .env.example、webhook mock、健康检查和日志字段,再接真实 secret,会比一次性连上所有外部服务安全得多。

实测后的结论

实际使用时,把任务拆小会明显提高 Claude Code 的输出质量。先 .dockerignore,再 Compose,再 health check,最后 CI,比一次生成所有内容更容易审查。命名 node_modules volume 和数据库 health gate 解决了最常见的两个新手问题:只在自己电脑能跑,以及 API 启动了但连不上 Postgres。

#Claude Code #Docker #containers #DevOps #infrastructure
免费

免费 PDF: Claude Code 速查表

输入邮箱即可获取一页 PDF,整理常用命令、审查习惯和安全工作流。

我们会妥善保护你的信息,不发送垃圾邮件。

把 Claude Code 变成真正能带来结果的工作流

先领取中文说明的免费 PDF,再进入英文商品页选择合适的教材。如果你需要团队落地、流程设计或内容变现支持,也可以直接咨询。

Masa

关于作者

Masa

专注 Claude Code 实务流程、团队导入和内容转化的工程师。