Docker多阶段构建的问题

时间:2019-05-09 10:45:40

标签: docker dockerfile

我遇到了一个多阶段构建的问题,其中将在第一阶段构建的二进制文件正确复制到了第二阶段,但是当您尝试运行它时,找不到可执行文件。

dockerfile是:

FROM golang as goimage
ENV SRC=/go/src/
RUN mkdir -p /go/src/
WORKDIR /go/src/go_docker
RUN git clone https://github.com/bryonbaker/simple-microservice.git /go/src/go_docker/ \
&& CGO_ENABLED=0 GOOS=linux GOARCH=amd64
RUN go get github.com/gorilla/mux
RUN go build -o bin/go_docker

FROM alpine:latest AS microservice
RUN apk --no-cache add bash
ENV WORK_DIR=/docker/bin
WORKDIR $WORK_DIR
COPY --from=goimage /go/src/go_docker/bin/ ./

# Put a container-image version identifier in the root directory.
ARG VERSION=1.0
RUN echo $VERSION > image_version

EXPOSE 10000
#CMD ["go_docker"]

结果是:

  

$ docker run -ti -p 80:10000 go-docker:latest
  / docker / bin#ls

     

go_docker image_version
  / docker / bin#./go_docker / bin / sh:   ./go_docker:找不到
  / docker / bin#

如果我从构建的中间goimage容器中运行二进制文件,那么它将运行良好。文件大小匹配...

注意:在此dockerfile中,我已注释掉CMD并通过外壳进行测试。如果取消对CMD的注释,则会遇到相同的问题:

  

docker运行go-docker:最新docker:来自守护程序的错误响应:OCI   运行时创建失败:container_linux.go:344:启动容器   进程导致“ exec:\“ go_docker \”:在以下位置找不到可执行文件   $ PATH”:未知。   ERRO [0001]错误等待容器:上下文已取消

如果您想查看它,我已经在git repo中公开了测试代码。

预先感谢

1 个答案:

答案 0 :(得分:1)

如果二进制文件的共享库不可用,您将在Linux上普遍收到此错误。 (在您的调试Shell中,尝试运行class Pages extends React.Component { constructor(props) { super(props); this.state = { pages: null, }; } componentDidMount() { axios.get('/pages') .then(response => { this.setState({ pages: response.data }) }); } render() { const { pages } = this.state; const { activePageNumber } = this.props; return pages ? ( <Page page={pages[activePageNumber]} /> ) : ( <div>loading...</div> ); } } 。)

您可能不希望使用动态链接的二进制文件,但是却得到了一个,因为shell和环境变量不会在ldd /docker/bin/go_docker命令之间传递。在RUN步骤的末尾设置CGO_ENABLED=0的地方,当实际的RUN在之后的两个步骤中运行时,该值会丢失。

(我还要稍微清理一下Dockerfile:容器内的路径之类的东西不需要是变量,并且使用系统路径来做是完全可以的。)

这给我们留下了

go build