首页/云/Docker 容器速查/RUN 合并命令减少层体积
镜像与构建107 条

RUN 合并命令减少层体积

把安装、配置、清理合并到一条 RUN:层是增量存储,前一层删掉的文件仍占体积,安装与清理必须同层完成。

Docker 容器速查云更新于 2026-10-13

合并执行指令是什么

把安装、配置与清理写进同一条执行指令里。原因是层是增量叠加的:在上一层删掉的文件,仍然存在于上一层里,体积不会减少。只有把安装与清理放在同一层,临时文件才不会进入最终镜像,同时层数也更少。

基本信息

串联方式用连接符把多条命令串成一条,前一条失败即中止
容错与打印命令开头加上遇错中止与打印执行的设置,便于定位问题
清理位置必须与安装同层,写在后续指令里等于没清理
层数影响减少层数有助于缩小体积,但过度合并会让缓存粒度变粗
适用平台所有使用构建描述的镜像构建流程

典型使用场景

  • 安装系统依赖:更新索引、安装、删除索引写在同一条里
  • 编译与清理:编译完成后删除临时产物,避免进入最终镜像
  • 批量创建目录:创建多个目录并统一设置属主,减少层数
  • 下载与解压:下载压缩包、解压、删除压缩包一条完成
  • 多步配置:需要按顺序执行的初始化动作串成一条,避免中间失败留下半截状态

推荐写法

推荐写法
RUN set -eux; \
    apt-get update; \
    apt-get install -y --no-install-recommends curl ca-certificates; \
    rm -rf /var/lib/apt/lists/*

# 反例:清理写在另一条指令里,上一层文件仍在
RUN apt-get update && apt-get install -y curl
RUN rm -rf /var/lib/apt/lists/*

合并与拆分的取舍

做法优势代价
合并安装与清理体积小,层数少局部改动会触发整条重建
按变更频率拆分缓存命中率高,构建快层数多一些,体积略增
全部合并成一条层数最少任何小改动都要重跑全部步骤
大量独立指令调试方便体积与层数都偏大

写合并指令的技巧

  • 按变更频率分组,系统依赖一组、应用依赖一组、源码一组
  • 安装与清理成对出现,中间不要插入与这两件事无关的步骤
  • 命令开头加容错设置,中间失败能立刻停下并打印执行过程
  • 换行书写提升可读性,注意续行符号的书写位置
  • 把包管理器缓存目录清干净,常见位置是系统包管理器的索引目录
容错设置让中间命令失败即中止,并打印每条正在执行的命令。构建日志会变长,但排查失败比逐条猜要快得多。
把无关命令塞进同一条会让缓存粒度变粗:改一个不相关的配置就要重跑整层。合并的边界应按变更频率来划,而不是单纯追求层数最少。

易错点

  • 清理写在另一条指令里,上层文件仍然存在,镜像体积没有变小
  • 合并过度导致任何小改动都触发整层重建,构建时间反而更长
  • 缺少容错设置时中间命令失败被忽略,构建成功但产物不完整
  • 续行符号写错导致命令被拆断,构建报错信息指向奇怪的位置

数据来源与参考

  • Docker 官方文档:Best practices for writing Dockerfiles(docs.docker.com)
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌