用 docker 基于 alpine 微型镜像部署 Go 的项目,启动时报错 panic: standard_init_linux.go:175: exec user process caused "no such file or directory"
通过 GOOS=linux GOARCH=amd64 go build 来构建是可以的,但是通过 golang 的 docker 镜像编译却不行,对比编译后的文件发现有猫腻。
本地编译:
> GOOS=linux GOARCH=amd64 go build
> file xxx
xxx: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, not stripped
golang docker 编译:
> docker run --rm -it -v $GOPATH:/go golang:1.7 bash -c 'cd $GOPATH/src/xxx && go build
> file xxx
xxx: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, not stripped
问题找到了,一个是静态链接,一个是动态链接,动态链接的在微型镜像 alpine 上不支持。
总结
默认 go 使用静态链接,但是在 docker 的 golang 环境中默认是使用动态编译。
如果想使用 docker 编译 + alpine 部署,可以通过禁用 cgoCGO_ENABLED=0 来解决。
如果要使用 cgo 可以通过 go build --ldflags “-extldflags -static” 来让 gcc 使用静态编译。