with one click
docker-best-practices
写 Dockerfile / 容器化应用时使用。镜像小、构建快、运行安全。
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Menu
写 Dockerfile / 容器化应用时使用。镜像小、构建快、运行安全。
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Based on SOC occupation classification
| name | docker-best-practices |
| description | 写 Dockerfile / 容器化应用时使用。镜像小、构建快、运行安全。 |
| category | devops |
| tags | ["docker","容器","镜像"] |
规则: 用多阶段构建(multi-stage build)将编译工具与运行时分离;最终阶段只保留运行所需;基础镜像使用 slim 或 alpine 变体并固定具体版本标签,不用 latest。
为什么: AI 生成 Dockerfile 时惯用 FROM node:latest 并把构建工具一并打进最终镜像,导致:镜像体积从几十 MB 膨胀到数百 MB,latest 标签在不同时间拉取内容不同使构建不可重复,安全扫描面随之大幅增加。曾见过把 gcc、make、完整 Python 开发头文件留在生产镜像里的真实事故。
怎么做:
FROM node:20-alpine AS builder 做编译,FROM node:20-alpine AS runtime 只拷产物。COPY --from=builder /app/dist ./dist 跨阶段拷贝,其余一概不带。docker scout 或 trivy 扫镜像,升版本时同步更新标签。规则: 把"依赖清单文件"(package.json、requirements.txt、go.mod 等)单独先 COPY 进去并执行安装,再 COPY 源码;源码修改不会使依赖层失效。
为什么: AI 最常见的写法是 COPY . . 然后 RUN npm install——每次改一行业务代码,整个依赖安装层失效,CI 上几分钟的 npm install 变成每次必跑。在依赖上百包的项目里这是显而易见的浪费,但 AI 很少主动意识到。
怎么做:
# 正确顺序:依赖清单 → 安装 → 源码
COPY package.json package-lock.json ./
RUN npm ci --omit=dev
COPY src/ ./src/
package.json 变化才重新跑 npm ci,改源码直接命中缓存。COPY 根 package.json 与各 workspace 的 package.json,再统一安装。规则: 用 USER 指令切换到无特权用户;通过 BuildKit secret 或运行时环境变量传入凭据,不用 ENV/ARG 把密钥固化进镜像层。
为什么: AI 生成的 Dockerfile 几乎从不加 USER 指令,容器进程默认以 root 运行,一旦容器被攻破即获宿主机高权限。同样,AI 会把 ARG NPM_TOKEN=xxx 写进 Dockerfile 并 RUN npm install,虽然 ARG 不出现在 docker inspect 环境变量里,但该层的文件系统快照仍可被 docker history 提取,密钥实质上已泄露。
怎么做:
# 创建专用用户
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser
# 用 BuildKit secret 挂载,不写进层
RUN --mount=type=secret,id=npm_token \
NPM_TOKEN=$(cat /run/secrets/npm_token) npm ci
docker run --env-file 或 Kubernetes Secret 注入,不烘进镜像。规则: 单个容器只运行一个主进程(PID 1);项目根目录维护 .dockerignore,至少排除 .git、node_modules、测试目录、本地配置文件等。
为什么: AI 有时会在同一容器里启动 Nginx + App Server + Cron,把运维复杂度全转移到容器内,违背容器设计原则,日志、健康检查、横向扩展都难以独立处理。同样,AI 不会主动创建 .dockerignore,导致 COPY . . 把几百 MB 的 node_modules 或整个 .git 历史拷入构建上下文,build context 传输时间急剧增加。
怎么做:
.git
node_modules
**/__tests__
**/*.test.ts
.env*
*.log
dist
规则: Dockerfile 内声明 HEALTHCHECK;应用代码监听 SIGTERM 并完成正在处理的请求后再退出,不强制杀进程。
为什么: AI 生成的镜像几乎不带 HEALTHCHECK,Kubernetes/Compose 只能靠进程存活判断容器状态,启动期间流量就被打过来导致报错。同样,AI 生成的 Node/Python 应用很少处理 SIGTERM,容器被 docker stop 时直接 SIGKILL,正在处理的请求被强制中断,数据库事务可能未提交。
怎么做:
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
CMD wget -qO- http://localhost:8080/health || exit 1
// Node.js 优雅退出示例
process.on('SIGTERM', async () => {
await server.close(); // 停止接收新连接
await db.end(); // 释放数据库连接池
process.exit(0);
});
console.log),不写文件,让容器运行时负责收集。# 反例
FROM node:latest # ❌ 不锁版本
WORKDIR /app
COPY . . # ❌ 先拷所有文件,层缓存极易失效
RUN npm install # ❌ 每次改任意文件都重跑
ENV JWT_SECRET=supersecret123 # ❌ 密钥固化进镜像层
EXPOSE 3000
CMD ["node", "server.js"] # ❌ root 用户运行,无 HEALTHCHECK
# ---- 构建阶段 ----
FROM node:20-alpine AS builder
WORKDIR /app
COPY package.json package-lock.json ./ # ✅ 先拷清单
RUN npm ci # ✅ 只在依赖变化时重跑
COPY src/ ./src/
RUN npm run build
# ---- 运行阶段 ----
FROM node:20-alpine AS runtime
WORKDIR /app
RUN addgroup -S app && adduser -S app -G app # ✅ 非 root 用户
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
USER app # ✅ 切换到无特权用户
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
CMD wget -qO- http://localhost:3000/health || exit 1 # ✅ 健康检查
EXPOSE 3000
CMD ["node", "dist/server.js"]
node:20-alpine),没有用 latest。COPY 并安装,层缓存策略正确。USER 指令)。ENV/ARG 或 COPY 把密钥固化进任何镜像层。.dockerignore,排除了 .git、node_modules、.env* 等无关文件。HEALTHCHECK,应用代码处理了 SIGTERM 优雅退出。做 Cocos Creator 多机型/多分辨率适配时使用。Canvas、Widget、安全区。
Cocos Creator 用 AssetBundle 做分包/远程资源时使用。加载、释放、依赖、缓存。
优化 Cocos Creator 渲染性能时使用。合批、图集、动静分离、Label。
给 Cocos Creator 原生包做热更新时使用。version manifest、增量、校验、回滚。
写 Cocos Creator 动效/动画时使用。tween、Animation、Spine、性能与清理。
做 Cocos Creator 大量条目列表时使用。虚拟列表、节点复用。