报错是这么冒出来的。阿里云 4 核 8G 的 Ubuntu 22.04 跑 Docker 24.0,前端项目改一行代码 docker build 就要重跑 npm install,耗时从 40 秒涨到 6 分钟,构建机上 /var/lib/docker 的 buildkit 缓存也在反复增长。

中间走过弯路,把「用 ADD 拉远程文件,URL 内容或响应头变化导致层摘要变化」当成主因,改完现象没变。

把日志和配置对完,能解释这个现象的基本就这几处。COPY . . 写在 npm install 之前,任何源码改动都会让后面的层全部重算。少数情况下是.dockerignore 没写,node_modules 和日志也进了构建上下文,内容每次都变。

还有一种情况,构建参数通过 ARG 注入时间戳,每次值不同直接把缓存打断。

第一件事是看构建日志里哪一层没有命中缓存

docker build --progress=plain -t web:test . 2>&1 | grep -i cache

只拷依赖清单再安装依赖

COPY package.json package-lock.json ./ && RUN npm ci

补上 .dockerignore 把大目录排除掉

printf 'node_modules\n.git\n*.log\n' > .dockerignore

最后再拷源码,让改动只影响最后一层

COPY . . && RUN npm run build

恢复的判定其实很直接。第二次构建日志里 npm ci 那一层显示 CACHED,总耗时回到 40 秒以内,镜像 digest 只有源码层发生变化。

这里还有个坑。缓存按层的文件内容摘要计算,mtime 不参与但内容参与;调整 COPY 顺序前先确认 .dockerignore 已经生效。同一份配置在测试环境跑通,不代表线上没事,两边的默认值经常不一样。

作者 9823189