构建缓存失效需逆向追踪断裂点:检查日志中“Using cache”是否中断,对比docker history层哈希,确认COPY/ADD文件内容、基础镜像RepoDigests或构建上下文(如.git、node_modules)是否隐性变更。

构建缓存失效本身不是报错,但它是很多看似“无故失败”或“行为突变”的底层原因。排查时不能只盯着错误信息,而要逆向追踪哪一层缓存意外中断、导致后续指令在非预期环境中执行——比如依赖没装全、路径不存在、权限错乱、甚至用了旧代码。
看构建日志里的“CACHED”标记是否突然中断
Docker 构建输出中每行开头会标 CACHED、Using cache 或直接执行命令。一旦某层没显示缓存命中,且你确认没改过对应指令或文件,就说明缓存链在此断裂。重点观察:
- 断裂点前一行是不是
COPY或ADD?检查它复制的文件内容是否被悄悄修改(如自动生成的版本号、时间戳、lock 文件哈希) - 断裂点是不是
FROM?运行docker inspect <基础镜像名>看RepoDigests是否变化,确认基础镜像是否被上游更新 - 断裂点是不是
RUN?回溯它的父层是否失效——即使该 RUN 命令字面没变,只要上一层变了,它就必须重跑
用 docker history 对比两版镜像的层指纹
对一次成功构建和一次失败构建生成的镜像,分别运行:
MiniMax 图片理解 + 网络搜索 MCP 工具。适配 Docker 环境(极空间等),支持图片 OCR 识别、图像内容理解、网络搜索。API Key 安全存储在本地 credentials 文件,不暴露在代码中。
docker history <image-id-or-tag>
对比各层的 IMAGE ID 和 CREATED BY。若某层 ID 不同,说明该层及之后全部重建。特别注意:
- 相同指令但不同 ID → 输入变了(文件内容、构建参数、基础镜像)
- 某层完全消失或顺序错位 → Dockerfile 被修改(哪怕只是加了空行或注释位置动了)
- 最后几层 ID 都不同,但前面一致 → 问题大概率出在 COPY 后的应用代码或构建时生成文件上
检查构建上下文有没有“隐形污染”
很多报错实际源于构建时把不该带的文件带进了上下文,触发了缓存重算或指令执行异常。典型表现是:本地构建正常,CI 上失败;或者每次构建结果不一致。
- 运行
tar -cf - . | tar -t | head -20(在构建目录执行),看是否有node_modules、.git、dist/、.env等不该出现的目录 - 确认
.dockerignore存在且生效:它必须放在构建上下文根目录,且规则区分大小写、支持通配符,但不支持**(除非用 BuildKit) - CI 中若用
git clone后构建,注意默认会带.git目录——即使没显式 COPY,Docker 仍会计算其哈希,导致缓存总不命中
验证多阶段构建中跨阶段 COPY 是否取到预期内容
缓存失效常让多阶段构建“拿错东西”:比如 builder 阶段因缓存未命中重跑了,但 runner 阶段却复用了旧缓存,导致 COPY --from=builder 拿到的是上一次构建的产物,而非最新编译结果。
- 给 builder 阶段加明确
target名称,构建时用--target builder单独验证该阶段输出 - 在 runner 阶段开头加临时调试命令,如
RUN ls -l /app/dist && cat /app/dist/version.txt,确认文件确实是本次生成的 - 避免
COPY --from=0这类序号引用,改用命名 stage,防止阶段增减导致错位

















