第01章:让Claude Code帮我写Dockerfile,它靠谱吗?

第01章:让Claude Code帮我写Dockerfile,它靠谱吗?

你让AI为你的应用写一个 Dockerfile。AI用了30秒,给了你一个看起来完整的文件。
你构建成功,容器能运行,你准备直接用它上线。

先等一下。这个 Dockerfile 是否真的适合生产?

这一章告诉你:AI生成的Dockerfile有哪些隐藏问题,以及如何用更好的提示词写出真正可以上线的镜像配置。


ℹ️ 版本说明:本章基于 Docker Engine 27.x,示例使用 Python 3.13 应用(FastAPI)。同样的问题和原则适用于 Node.js、Go 等其他技术栈。


1.1 AI默认会生成什么

你告诉AI:“为我的 FastAPI 应用写一个 Dockerfile”,AI通常给你这个:

FROM python:3.13

WORKDIR /app

COPY requirements.txt .
RUN pip install -r requirements.txt

COPY . .

EXPOSE 8000

CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]

这个 Dockerfile 能用,能构建成功,容器也能跑起来。但它有5个问题。


1.2 AI通常遗漏的5个坑

⚠️ 坑1:用了 python:3.13(全量镜像,1GB+)

python:3.13 是基于 Debian 的完整镜像,包含编译器、开发工具、头文件……你的应用运行根本不需要这些。
镜像大小:约 1.0GB

使用 python:3.13-slimpython:3.13-alpine

  • slim:约 150MB,基于 Debian 精简版,兼容性好,推荐首选
  • alpine:约 50MB,基于 Alpine Linux,更小但 C 扩展包(numpy/pandas)编译可能出错

⚠️ 坑2:以 root 用户运行容器(安全风险)

AI生成的 Dockerfile 没有 USER 指令,容器默认以 root 身份运行。
如果你的应用有任意代码执行漏洞,攻击者可以在容器内以 root 权限执行命令,
并可能通过卷挂载或特权模式逃逸到宿主机。

正确做法:创建专用非 root 用户,切换到该用户运行应用。

⚠️ 坑3:COPY . . 把不必要的文件(甚至密钥)打包进镜像

.git/.envnode_modules/__pycache__/、本地配置文件……
如果没有 .dockerignoreCOPY . . 会把这些全部打包进镜像。
更危险的是:如果 .env 里有 API Key,这些密钥会永久嵌入镜像层,即使之后删除文件,
在旧的镜像层里仍然可以提取出来。

⚠️ 坑4:没有健康检查(HEALTHCHECK)

容器启动了不等于应用健康了。应用可能启动成功但数据库连接失败,
或者启动后过一段时间因为内存泄漏变成无响应状态。
没有 HEALTHCHECK,Docker 和 Kubernetes 无法检测到这些情况,
会继续给"假运行"的容器发送流量。

⚠️ 坑5:没有固定依赖版本(pip install -r requirements.txt 不够稳定)

requirements.txt 里如果写的是 fastapi 而不是 fastapi==0.115.0
每次重新构建镜像可能安装不同版本,导致"本地跑通,CI构建却出错"。


1.3 更好的提示词

提示词 P01:生成生产级 Dockerfile

使用时机:为任何应用编写第一个生产可用的 Dockerfile。

你是一个 Docker 27 生产环境专家。

请为以下应用生成生产可用的 Dockerfile 和 .dockerignore:

应用信息:
- 语言/框架:[如:Python 3.13 + FastAPI 0.115 / Node.js 22 + Express]
- 启动命令:[如:uvicorn main:app --host 0.0.0.0 --port 8000]
- 监听端口:[如:8000]
- 是否需要编译(C扩展/Go编译等):[如:不需要 / 有 numpy 依赖]

生产要求(每一条都必须实现):
1. 基础镜像:使用 slim 变体,不用全量镜像(说明 slim vs alpine 的选择理由)
2. 非root用户:创建专用用户(如 appuser),切换到该用户运行
3. .dockerignore:列出所有不应打包进镜像的文件和目录
4. 健康检查(HEALTHCHECK):检查应用的 /health 接口,配置合理的重试和超时
5. 依赖锁定:说明如何生成并使用 requirements.txt 的锁定版本(pip freeze 或 pip-compile)
6. 构建缓存优化:COPY 顺序应最大化利用 Docker 层缓存

给出完整的 Dockerfile,每一条指令都加注释说明用途,  
并指出"如果不这样写,会发生什么后果"。

提示词 P02:Review 现有 Dockerfile

使用时机:你已有一个 Dockerfile,想检查它是否适合生产。

你是一个 Docker 27 安全和性能审计专家。

请对以下 Dockerfile 做生产环境 Review:

[粘贴你的 Dockerfile]

按以下维度逐一检查,对每个问题给出严重程度(⛔高危 / ⚠️中危 / 💡建议)和修复方案:

1. 基础镜像安全
   - 是否使用了已知漏洞较多的基础镜像?(如老版本 ubuntu、latest tag)
   - 是否用了 latest tag?(应该用固定版本)
   - 镜像大小是否合理?

2. 用户权限
   - 是否以 root 运行?(生产环境应使用非 root 用户)

3. 数据安全
   - .dockerignore 是否正确排除了 .env、.git、密钥文件?
   - 是否有在 RUN 命令里传入密码/密钥的写法(会留在镜像层)?

4. 应用健康
   - 是否有 HEALTHCHECK?
   - CMD/ENTRYPOINT 是否使用 exec 格式(["uvicorn"...] 而不是字符串格式)?
   - 是否处理了 SIGTERM 信号(优雅关机)?

5. 构建效率
   - 是否存在每次都重新安装依赖的层顺序问题?
   - 是否有可以移除的不必要文件(如测试文件、文档)?

给出修改后的完整 Dockerfile。

提示词 P03:为不同语言/框架生成对应的 Dockerfile 模板

使用时机:你的项目用了特定的技术栈,需要针对性的最佳实践。

你是一个 Docker 27 多语言专家。

请为以下技术栈生成生产级 Dockerfile 模板,并说明该栈的特殊注意事项:

技术栈:[选择一个:
- Node.js 22 LTS + npm/pnpm(包含 node_modules 的处理)
- Go 1.23(使用多阶段构建:build stage + scratch/distroless 运行)
- Python 3.13 + Poetry(使用 poetry install --no-dev)
- Java 21 + Maven(使用 multi-stage build 减小运行时镜像)
]

特别注意:
- 针对这个技术栈,有哪些常见的"AI会犯但开发者忽略"的错误?
- 依赖安装如何最大化缓存利用?
- 该语言的进程信号处理(SIGTERM)有什么特殊性?
- 推荐的基础镜像是什么?(说明理由)

给出带完整注释的 Dockerfile,适合作为项目模板复用。

1.4 Dockerfile 验收清单

检查项 验证方法 AI辅助
使用 slim 或精简基础镜像 docker image ls 查看镜像大小(应 < 500MB) 用P01重新生成,指定slim镜像
非 root 用户运行 docker run --rm image whoami(应该不是root) 用P02检查USER指令
.dockerignore 存在且正确 docker build 时检查 context size(应 < 10MB) 用P01生成.dockerignore
有 HEALTHCHECK docker inspect image | grep Health 用P01要求加入HEALTHCHECK
没有 latest tag(固定版本) 检查 FROM 指令 用P02审查基础镜像tag
层顺序正确(依赖层在应用层前) 修改代码后,docker build应该命中缓存(not “RUN pip install”) 用P02检查层顺序

1.5 本章小结

如果你只记一件事
AI生成的 Dockerfile 默认使用全量镜像 + root用户 + 没有HEALTHCHECK。
上线前三件事:换 slim 镜像、加 非root用户、写好 .dockerignore
用 P01 一次性生成包含这五个要点的生产级 Dockerfile。


→ 第02章:AI写的多阶段构建,镜像真的小又安全吗?