我们期望使用docker来跑golang程序,Dockerfile示例:
FROM golang:1.14 as builder ARG SERVICE="" ADD . /go/src/$SERVICE WORKDIR /go/src/$SERVICE RUN go build -mod=vendor -o main FROM alpine:3.12 ARG SERVICE="" WORKDIR /opt COPY --from=builder /go/src/$SERVICE/main /opt COPY ./config.sample.json /opt/config.json ENTRYPOINT ["/opt/main", "-c", "/opt/config.json"]
构建docker镜像:
docker build --build-arg SERVICE=myapp -t hello:test .
然后运行这个镜像:
docker run --rm hello:test // 出现报错 standard_init_linux.go:211: exec user process caused "no such file or directory"
查了许久,发现是因为我们把代码编译成可执行的二进制文件后,它仍然动态链接到运行所需的库(比如C库等),而在 alpine 这个精简的Linux系统中并没有。我们需要修改一下编译选项:
CGO_ENABLED=0 GOOS=linux go build -a -mod=vendor -o main
通过禁用 cgo 将其变为静态二进制文件,同时也指定了操作系统为 linux,-a表示重新编译我们使用的包(所有import都会以禁用cgo的形式重新编译一次)。
参考:https://rollout.io/blog/building-minimal-docker-containers-for-go-applications/
Add Comment