← ClaudeAtlas

docker-best-practiceslisted

写 Dockerfile / 容器化应用时使用。镜像小、构建快、运行安全。
Wade-DevCode/awesome-coding-skills-cn · ★ 3 · DevOps & Infrastructure · score 78
Install: claude install-skill Wade-DevCode/awesome-coding-skills-cn
# Docker 最佳实践 ## 何时用 - 新写或修改任何 Dockerfile。 - 把现有应用容器化时做方案设计。 - 发现镜像体积异常大、构建反复拉依赖、容器以 root 身份运行时。 - 做镜像安全扫描前的自查。 ## 核心规则 ### 1. 多阶段构建 + 锁定基础镜像版本 **规则:** 用多阶段构建(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` 跨阶段拷贝,其余一概不带。 - 在 CI 中定期用 `docker scout` 或 `trivy` 扫镜像,升版本时同步更新标签。 --- ### 2. 善用层缓存:先装依赖再拷源码 **规则:** 把"依赖清单文件"(`package.json`、`requirements.txt`、`go.mod` 等)单独先 `COPY` 进去并执行安装,再 `COPY` 源码;源码修改不会使依赖层失效。 **为什么:** AI 最常见的写法是 `COPY . .` 然后 `RUN npm install`——每次改一行业务代码,整个依赖安装层失效,CI 上几分钟的 `npm install` 变成每次必跑。在依赖上百包的项目里这是显而易见的浪费,但 AI 很少主动意识到。 **怎么做:** ```dockerfile # 正确顺序:依赖清单 → 安装 → 源码 COPY package.json package-lock.json ./ RUN npm ci --omit=dev COPY src/ ./src/ ``` - 每次只有 `package.json` 变化才重新跑 `npm ci`,改源码直接命中缓存。 - monorepo 场景先 `COPY` 根 `package.json` 与各 workspace 的 `package.json`,再统一安装。 --- ### 3. 不以 root 运行;密钥不进镜像 **规则:** 用 `USER` 指令切换到无特权用户;通过 BuildKit secret 或运行时环境变量传入凭据,不用 `ENV`/`ARG` 把密钥固化进镜像层。 **为什么:** AI 生成的 Dockerfile 几乎从不加 `USER` 指令,容器进程默认以 root 运行,一旦容器被攻破即获宿主机高权限。同样,AI 会把 `ARG NPM_TOKEN=xxx` 写进 Dockerfile 并 `RUN npm install`,虽然 `ARG` 不出现在 `docker inspect` 环境变量里,但该层的文件系统快照仍可被 `docker history` 提取,密钥实质上已泄露。 **