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

xpt*_*xpt 1 build go docker

我正在尝试将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
Run Code Online (Sandbox Code Playgroud)

它使用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.
Run Code Online (Sandbox Code Playgroud)

更新:

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

ENTRYPOINT ["/myapp"]
Run Code Online (Sandbox Code Playgroud)

完成此操作后,我收到了一个新错误:

standard_init_linux.go:207: exec user process caused "no such file or directory"
Run Code Online (Sandbox Code Playgroud)

使用较小的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"
Run Code Online (Sandbox Code Playgroud)

如何解决?谢谢!

Dav*_*aze 9

Dockerfile的最后一行是

ENTRYPOINT /myapp
Run Code Online (Sandbox Code Playgroud)

ENTRYPOINT(以及CMD和RUN)指令有两种形式。一个“EXEC形式”看起来像一个JSON列表,并提供的参数作为主容器进程中运行的未解释的列表。一个“壳形”看起来并不像一个JSON列表,并含蓄地裹着/bin/sh -c '...'

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

ENTRYPOINT ["/myapp"]
Run Code Online (Sandbox Code Playgroud)

  • 还值得一提的是,使基本映像“从零开始”也会损害Vanilla Go代码的某些功能(至少是开箱即用的),例如解析SSL或依赖于底层OS的其他功能(缺少此功能)。 / bin / sh)。这就是为什么我们通常使用较小的Linux映像作为基础(即Alpine Linux)而不是从头开始的原因。 (2认同)