第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-slim 或 python:3.13-alpine:
slim:约 150MB,基于 Debian 精简版,兼容性好,推荐首选alpine:约 50MB,基于 Alpine Linux,更小但 C 扩展包(numpy/pandas)编译可能出错
⚠️ 坑2:以 root 用户运行容器(安全风险)
AI生成的 Dockerfile 没有 USER 指令,容器默认以 root 身份运行。
如果你的应用有任意代码执行漏洞,攻击者可以在容器内以 root 权限执行命令,
并可能通过卷挂载或特权模式逃逸到宿主机。
正确做法:创建专用非 root 用户,切换到该用户运行应用。
⚠️ 坑3:COPY . . 把不必要的文件(甚至密钥)打包进镜像
.git/、.env、node_modules/、__pycache__/、本地配置文件……
如果没有 .dockerignore,COPY . . 会把这些全部打包进镜像。
更危险的是:如果 .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写的多阶段构建,镜像真的小又安全吗?