Docker运行提示exec /main不存在但文件实际存在的问题求助
Go二进制在Alpine容器中存在却无法运行的解决办法
问题场景
我的Dockerfile内容如下:
FROM alpine:latest COPY ./main . COPY ./configs/. . EXPOSE 8081 CMD ["/main"]
进入容器后能看到/main文件存在且有可执行权限:
/ # ls -lart /main -rwxrwxr-x 1 root root 15352712 May 29 19:16 /main
但无论直接运行容器还是在容器内执行/main,都会提示"no such file or directory",我用的是Ubuntu22.04,Docker版本20.10.21,这是Docker的bug吗?
问题本质
这不是Docker的bug,核心原因是Go二进制的动态链接依赖与Alpine系统不兼容:
- Alpine Linux采用轻量的
musl libc,而你在Ubuntu(基于glibc)上默认编译的Go程序,是链接glibc的。 - 系统找不到对应的动态链接器,所以抛出"文件不存在"的错误(这个提示有误导性,实际是依赖缺失,不是文件本身找不到)。
验证方法
进入容器执行ldd /main,会看到类似输出,明确显示glibc相关依赖无法找到:
/ # ldd /main /lib64/ld-linux-x86-64.so.2: (0x7f9...) libc.so.6 => /lib64/ld-linux-x86-64.so.2 (0x7f9...) Error relocating /main: __vfprintf_chk: symbol not found Error relocating /main: __fprintf_chk: symbol not found
解决办法
方案一:静态编译Go程序
编译时生成静态链接的二进制,脱离系统libc依赖,执行以下命令编译:
CGO_ENABLED=0 GOOS=linux go build -o main main.go
重新构建镜像后,Alpine容器即可正常运行程序。
方案二:改用基于glibc的基础镜像
修改Dockerfile的基础镜像为ubuntu:latest或debian:stable-slim这类基于glibc的镜像,无需调整编译命令,直接构建即可运行:
FROM ubuntu:latest COPY ./main . COPY ./configs/. . EXPOSE 8081 CMD ["/main"]
内容的提问来源于stack exchange,提问作者Dean Schulze
相关产品推荐
相关产品推荐

