You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Docker多阶段构建中清理npm缓存与node_modules是否必要?

关于Docker多阶段构建中npm缓存与清理命令的疑问

我正在学习Docker,最初使用的Dockerfile如下:

FROM node
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build && npm cache clean --force && rm -rf node_modules
CMD ['npm', 'start']

了解多阶段构建后,我将Dockerfile修改为:

FROM node AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

FROM node:lts-alpine
WORKDIR /app
COPY --from=builder /dist /app
CMD ['npm', 'start']

我本以为可以移除npm cache clean --force && rm -rf node_modules,因为这些产物不会出现在最终镜像中,还能加快构建速度。但看到资料称这些产物仍会留在缓存中占用空间。

于是我做了测试:

  • 执行docker builder prune --all;
  • 保留清理命令构建镜像;
  • 再次执行docker builder prune --all,清理后总占用912.7MB;
  • 移除清理命令构建镜像;
  • 再次执行docker builder prune --all,清理后总占用仍为912.7MB。

构建后执行docker history <image>也未发现差异。请问:

  1. npm缓存和node_modules是否真的会被Docker缓存占用空间?
  2. 我能否使用无清理命令的Dockerfile以提升速度?
  3. 保留清理命令是否属于最佳实践?

解答

1. npm缓存和node_modules是否会占用Docker构建缓存空间?

是的,但你的测试结果无差异,是因为docker builder prune --all会彻底清理所有未被使用的构建缓存(包括builder阶段产生的中间层)。在多阶段构建中,builder阶段的node_modules和npm缓存确实会作为中间层保存在构建缓存里,但只要你不保留builder阶段的镜像,且定期清理缓存,这些临时产物不会长期占用空间。

需要注意:如果构建频繁重复,且builder阶段的层没有变动(比如package*.json没修改),Docker会复用这些缓存层,此时node_modules和npm缓存会一直存在于缓存中,直到你手动清理或者缓存被新的构建覆盖。

2. 能否使用无清理命令的Dockerfile提升构建速度?

完全可以。移除清理命令后,builder阶段的node_modules和npm缓存会被保留在构建缓存中,当后续构建时如果package*.json没有变化,Docker会直接复用RUN npm ci的缓存层,跳过重新安装依赖的步骤,大幅提升构建速度。

而且由于多阶段构建的最终镜像只复制/dist目录,这些缓存产物根本不会进入最终镜像,完全不影响最终镜像的大小。

3. 保留清理命令是否属于最佳实践?

在多阶段构建的builder阶段,保留清理命令已经不是最佳实践,原因如下:

  • 增加构建时间:每次构建都要执行npm cache clean和rm -rf node_modules,反而拖慢构建速度;
  • 导致缓存失效:清理命令会让RUN npm run build && ...这一层无法被复用,即使代码没有变动,也需要重新构建;
  • 无实际收益:这些产物不会进入最终镜像,只要定期清理构建缓存(比如用docker builder prune),就不会造成空间浪费。

唯一的例外场景是:如果你的构建环境磁盘空间极其紧张,且无法定期执行缓存清理,此时在builder阶段清理临时产物可以减少缓存占用的瞬时空间,但这种情况非常少见。

内容的提问来源于stack exchange,提问作者Noberto Pessoa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 10:47:39