package.json声明项目元数据与依赖范围,package-lock.json锁定所有依赖(含嵌套)的确切版本、来源及完整性哈希,确保多环境安装一致。
调整指令顺序的核心逻辑是:把变动少、稳定性高的操作往前放,让它们更早生成可复用的层;把频繁修改的部分往后放,避免牵连前面已缓存的步骤。
先复制依赖文件,再安装依赖
比如 Node.js 项目中,package.json 和 package-lock.json 很少改动,而源码每天都在变。如果先把所有文件 COPY 进去,哪怕只改了一个 .js 文件,整个构建上下文就变了,RUN npm install 这一层就无法命中缓存。
正确写法:
COPY package.json package-lock.json ./-
RUN npm install(这一步能稳定复用缓存) -
COPY . .(源码最后复制,不影响前面)
合并 RUN 指令减少层数
每条 RUN 都会新增一层。如果写成多条独立命令,中间某步变了,后面全得重来。例如:
- 错误写法:
RUN apt-get update && apt-get install -y curl和RUN apt-get install -y git是两层,后者变更会导致前者缓存虽在但无法跳过 - 推荐写法:
RUN apt-get update && apt-get install -y curl git && rm -rf /var/lib/apt/lists/*,一次完成,减少层、提升复用率
把 ENV 和 ARG 放在靠前且稳定的位置
环境变量和构建参数会影响后续 RUN 指令的执行结果。如果它们在 Dockerfile 中间被修改,或使用了动态值(如 --build-arg VERSION=$(date)),就会破坏缓存链。
建议:
- ENV 尽量定义在基础设置阶段,不随构建过程变化
- ARG 若需传入,应在 FROM 后立即声明,并配合固定值或 CI 环境中可控的变量
- 避免在 RUN 命令中拼接未声明的变量,防止隐式依赖导致缓存不一致
用 .dockerignore 排除干扰文件
COPY 指令的缓存是否命中,取决于它所引用文件的实际内容哈希。如果构建上下文中混入了日志、临时文件、node_modules 或 .git 目录,哪怕没被 COPY 到镜像里,只要它们出现在上下文路径中,某些构建模式(尤其旧版 Docker)仍可能影响哈希计算。
确保 .dockerignore 包含:
node_modules.git*.log-
dist/、build/(若非必需)










