合理编写 run 指令可减少镜像层数、降低体积、提升缓存命中率;需合并命令、同步清理、按变更频率排序、锁死版本、慎用路径切换。

RUN 指令写得合理,能显著减少镜像构建时间、降低层体积、提升缓存命中率。核心是:合并命令、避免无效操作、提前利用缓存、精简中间产物。
合并多条 RUN 命令为一条
Docker 每个 RUN 都会生成新层,前一层的文件即使被删除,仍保留在镜像中。合并能减少层数、避免残留文件、提升缓存复用率。
❌ 不推荐:
RUN apt-get update<br>RUN apt-get install -y curl wget<br>RUN rm -rf /var/lib/apt/lists/*
✅ 推荐(单层执行 + 清理同步):
RUN apt-get update && \<br> apt-get install -y curl wget && \<br> rm -rf /var/lib/apt/lists/*
- 用 && 连接,确保任一命令失败则整条 RUN 失败(符合预期)
- 清理动作必须和安装放同一层,否则 /var/lib/apt/lists/ 仍会残留
- 换行用反斜杠 \ 提高可读性,但注意行尾不能有空格
按“变更频率”从低到高组织操作顺序
把不常变动的操作(如系统更新、基础依赖安装)放在前面,高频改动(如复制源码、编译)放后面,让缓存尽可能复用。
- 先 RUN 安装工具链、系统库(很少改)
- 再 COPY 项目依赖描述文件(如 package.json、requirements.txt),单独 RUN 安装依赖
- 最后 COPY 源码、RUN 构建或启动命令
这样改了代码也不会触发重新下载依赖,大幅提升二次构建速度。
避免在 RUN 中使用易变参数或随机内容
任何导致指令哈希值变化的操作都会使缓存失效。常见陷阱包括:
- 用 curl https://.../latest.tar.gz —— URL 不变但内容变 → 缓存失效
- 用 date、uuidgen、git clone 默认拉最新 commit(无固定 ref)
- 未指定软件版本,如 pip install flask → 下次可能装新版,哈希不同
✅ 正确做法:
- 下载固定 URL 或带校验(如 SHA256)的归档
- git clone -b v1.2.0 --depth 1 指定 tag 和浅克隆
- pip install flask==2.3.3 锁死版本;或先 COPY requirements.txt 再 pip install -r
慎用 WORKDIR + 多次 RUN 切换目录
每个 RUN 默认在镜像根目录执行,频繁 cd 容易出错且影响可读性。更稳妥的方式是:
- 用 WORKDIR /app 设定默认工作目录(只写一次)
- 后续所有 RUN 自动在此路径下执行,无需 cd /app && xxx
- 若某条命令必须在其他路径运行,显式用 cd /tmp && ...,但尽量少用
既清晰又避免因路径错误导致缓存失效或构建失败。











