多阶段Dockerfile运行二进制提示无此文件或目录错误如何解决
报错根因
你判断的路径引用错误并不准确,这个报错绝大多数场景是二进制依赖的动态链接库缺失导致的,和路径配置无关:
- 你使用的
golang:alpine基础镜像默认开启CGO,编译出的Go二进制会动态依赖alpine自带的musl libc库,但第二阶段的scratch是完全空白的空镜像,没有任何系统依赖库,系统加载二进制时找不到对应的依赖文件,就会抛出这个"no such file or directory"报错。 - 你可以自行验证路径是否正确:临时将第二阶段基础镜像替换为
alpine,执行docker run --rm <你的镜像名> ls /app/server,如果能正常输出文件信息,就说明路径配置完全正确。
修复方案
修改第一阶段的Go编译命令,禁用CGO强制生成静态链接二进制即可:
将原来的编译指令
RUN go build -o server .
替换为:
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o server .
参数说明:
CGO_ENABLED=0:禁用CGO,强制生成无外部动态依赖的静态二进制文件GOOS=linux:明确指定编译目标为Linux系统,避免在Mac/Windows等非Linux环境构建时出现系统不兼容问题-a:强制重新编译所有依赖包,避免缓存的动态编译包影响结果-installsuffix cgo:给静态编译的依赖包添加独立后缀,避免和动态编译缓存混淆
如果修改后仍有报错,可以根据运行环境的CPU架构补充GOARCH参数,比如x86环境加GOARCH=amd64,arm64环境加GOARCH=arm64。
WORKDIR作用范围说明
WORKDIR参数只会作用于当前所在的构建阶段,不会跨阶段传递。
你在第一阶段builder镜像中设置的WORKDIR /app,对第二阶段全新的scratch镜像完全不生效,因此你第二阶段COPY时写全路径/app/server的操作是正确的,无需调整。
内容的提问来源于stack exchange,提问作者Jason Salas
相关产品推荐
相关产品推荐

