我正在尝试将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"
如何解决?谢谢!
答案 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"]