2021-03-26
解决:Docker scratch镜像运行Golang二进制程序报错
错误症状:
Centos环境下的构建命令(目标环境也是Linux,因此不需要交叉编译):
go build -o /home/docker/go/hbxin/hbxin_linux .
先看Dockerfile:FROM scratch
FROM scratch ADD ./ /bin WORKDIR /bin/ EXPOSE 80 CMD ["./hbxin_linux"]
构建Docker镜像并运行后,直接报错:
standard_init_linux.go:211: exec user process caused "no such file or directory"
谷歌答案都很分散,最终经过研究,解决方案如下:
改用静态编译
go build -a -ldflags '-linkmode external -extldflags "-static"' -o /home/docker/go/hbxin/hbxin_linux .
编译时间会稍长,但直接报错了:
/usr/local/go/pkg/tool/linux_amd64/link: running gcc failed: exit status 1
/usr/bin/ld: cannot find -ldl
/usr/bin/ld: cannot find -lpthread
/usr/bin/ld: cannot find -ldl
/usr/bin/ld: cannot find -lc
collect2: error: ld returned 1 exit status
安装缺少的库
yum install glibc-static -y
重新执行静态编译,报出如下警告,无视即可,实际上go程序已经可以在docker正常运行了:
go build -a -ldflags '-linkmode external -extldflags "-static"' -o /home/docker/go/hbxin/hbxin_linux . /tmp/go-link-356033486/000015.o: In function `unixDlOpen': /www/go/pkg/mod/github.com/mattn/go-sqlite3@v1.14.5/sqlite3-binding.c:39981: warning: Using 'dlopen' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking /tmp/go-link-356033486/000004.o: In function `_cgo_26061493d47f_C2func_getaddrinfo': /tmp/go-build/cgo-gcc-prolog:58: warning: Using 'getaddrinfo' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking