在Docker中构建干净的Go应用程序

时间:2019-05-04 18:19:42

标签: docker go build

我正在尝试将Go Web服务器创建为小型Docker映像。理想情况下,干净的图像仅包含Go应用程序本身(并可能支持Web组件,而不包含Go构建环境)。

这是我的Dockerfile

# golang:latest as build-env
FROM golang:latest AS build-env

RUN mkdir /app
ADD . /app/
WORKDIR /app
RUN cd /app && GO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o myapp .
# go build -o myapp

FROM scratch
COPY --from=build-env /app/myapp /app/images /

EXPOSE 8080
ENTRYPOINT /myapp

它使用Docker Builder模式和临时映像,这是一个空的特殊Docker映像。

它构建正常,但是当我运行它时,我得到:

docker: Error response from daemon: OCI runtime create failed: container_linux.go:344: starting container process caused "exec: \"/bin/sh\": stat /bin/sh: no such file or directory": unknown.

更新:

因此,ENTRYPOINT需要更改为exec形式:

ENTRYPOINT ["/myapp"]

这样做之后,我收到了一个新错误:

standard_init_linux.go:207: exec user process caused "no such file or directory"

使用较小的Linux映像作为基础(即Alpine Linux)而不是从头开始也无济于事:

$ docker run -it -p 8080:8080 go-web-docker-small            
standard_init_linux.go:207: exec user process caused "no such file or directory"

$ docker run -it -p 8080:8080 go-web-docker-small /bin/sh -i 
standard_init_linux.go:207: exec user process caused "no such file or directory"

如何解决?谢谢!

2 个答案:

答案 0 :(得分:8)

Dockerfile的最后一行是

ENTRYPOINT /myapp

有两种形式的ENTRYPOINT(以及CMD和RUN)指令。 "exec form"看起来像一个JSON列表,并提供了一个未解释的参数列表作为主容器进程运行。 "shell form"看起来不像JSON列表,而是隐式包装在/bin/sh -c '...'中。

您的ENTRYPOINT使用shell形式,而FROM scratch图像没有shell,从而产生错误。您可以将其更改为exec表单

ENTRYPOINT ["/myapp"]

答案 1 :(得分:2)

在构建您提供的Dockerfile时,出现以下错误:

  

复制失败:stat / var / lib / docker / overlay2 / cc1f8144192760ce7bf9cda7a7dfd0af16065901594c38609c813ea103cfd8d7 / merged / app / images:没有此类文件或目录

修复了复制命令以及其他一些问题,并且在Dockerfile中使用以下命令构建了映像

# golang:latest as build-env
FROM golang:latest AS build-env

RUN mkdir /app
ADD . /app/
WORKDIR /app
RUN cd /app && GO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o myapp .
# go build -o myapp

FROM scratch
COPY --from=build-env /app/myapp .

EXPOSE 8080
ENTRYPOINT ["./myapp"]