多阶段构建里,COPY --from=<stage> 的源路径并不相对源阶段的 WORKDIR 解析,而是相对目标阶段根目录。所以跨阶段 COPY 时,相对路径会指向错误位置,报 “No such file or directory”。

现象

Docker 多阶段构建时,builder 阶段设置了 WORKDIR /src,文件实际位于 /src/internal/xmlbuild/cpu_rule.json 和 /src/cmd/configs/compute.yaml。

但 COPY --from=builder 后,internal/... 这种相对路径会被解析为相对于 /(即 /internal/...),而不是相对于 WORKDIR /src。

所以 Docker 找不到文件。

排查

先确认报错是不是 “No such file or directory”,且文件确实存在于源阶段。

再检查 COPY 的源路径写法,看是否用了相对路径。

根因

多阶段构建中,COPY --from=<stage> 的源路径是相对于构建上下文或目标阶段的根目录解析的,而不是相对于源阶段的 WORKDIR。

也就是说,COPY --from=builder 之后,就不能用上一个阶段的相对路径了。

比如你写:

FROM builder AS build
WORKDIR /src
# ... 构建,生成 /src/internal/xmlbuild/cpu_rule.json

FROM scratch
COPY --from=build internal/xmlbuild/cpu_rule.json /app/

这里的 internal/xmlbuild/cpu_rule.json 会被解析为 /internal/xmlbuild/cpu_rule.json,而不是 /src/internal/xmlbuild/cpu_rule.json,自然找不到文件。

解决办法是写绝对路径,或带上 WORKDIR 前缀:

# 方式一:绝对路径
COPY --from=build /src/internal/xmlbuild/cpu_rule.json /app/

# 方式二:相对 WORKDIR 的路径
COPY --from=build src/internal/xmlbuild/cpu_rule.json /app/

小结

  • COPY --from=<stage> 的源路径是相对于目标阶段根目录解析的,不是相对于源阶段的 WORKDIR;
  • 跨阶段 COPY 时,务必使用绝对路径或带上 WORKDIR 前缀;
  • 这类问题报错往往很隐晦(“No such file or directory”),但根因就是路径解析规则。