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