多阶段构建无法从前一个阶段运行ENTRYPOINT – 没有此文件或目录。

huangapple go评论106阅读模式
英文:

Multi-stage build cannot run ENTRYPOINT from previous stage - no such file or directory

问题

我有一个由golang创建的子项目。

我想将其构建成镜像并上传到Google Cloud的Artifact Registry。

这样,我就可以使用这个镜像在Google Cloud上创建作业并运行它。

项目的结构如下所示:

  1. application
  2. hello
  3. firstJob
  4. main.go
  5. go.mod
  6. go.sum
  7. main.go

go.mod的内容非常简单,如下所示:

  1. module github.com/demo/first-sub-project
  2. go 1.19

位于firstJob文件夹中的main.go将引用根目录中的go.mod。

hello/firstJob/main.go的内容如下所示:

  1. package main
  2. import (
  3. "log"
  4. "github.com/caarlos0/env"
  5. "github.com/demo/first-sub-project/application"
  6. )
  7. func main() {
  8. cfg := application.Config{}
  9. err := env.Parse(&cfg)
  10. if err != nil {
  11. log.Fatalf("parse config error: %v", err)
  12. }
  13. log.Println("Finish")
  14. }

我有以下Dockerfile:

  1. # 参考 https://github.com/GoogleCloudPlatform/cloud-run-hello/blob/master/placeholder.dockerfile
  2. FROM golang:1.19-buster as builder
  3. WORKDIR /app
  4. COPY go.mod go.sum ./
  5. RUN go mod download
  6. COPY . ./
  7. RUN go build -o job github.com/demo/first-sub-project/hello/firstJob
  8. FROM alpine:3
  9. RUN apk add --no-cache ca-certificates
  10. COPY --from=builder /app/job /job
  11. ENV TZ=Asia/Tokyo
  12. ENTRYPOINT ["/job"]

我可以成功构建和推送镜像容器到Google Cloud,并在Google Cloud上创建作业。

但是当我运行作业时,会显示以下错误消息:

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

如果我将hello/firstJob/main.go更改为以下内容,它将正常工作:

  1. package main
  2. import (
  3. "log"
  4. "github.com/caarlos0/env"
  5. )
  6. type Config struct {
  7. Port int
  8. }
  9. func main() {
  10. cfg := Config{}
  11. err := env.Parse(&cfg)
  12. if err != nil {
  13. log.Fatalf("parse config error: %v", err)
  14. }
  15. log.Println("Finish")
  16. }

似乎在运行Dockerfile中的ENTRYPOINT时,它无法找到先前阶段的包路径。

我该如何解决这个问题?

英文:

I have the sub project that was made by golang.

I want to build it into the image and upload to the Artifact Refistry to the google cloud.

So I can use this image to create job and run it on the google cloud.

The structure of project is like this:

  1. application
  2. hello
  3. firstJob
  4. main.go
  5. go.mod
  6. go.sum
  7. main.go

The content of go.mod is very simple, like this as below:

  1. module github.com/demo/first-sub-project
  2. go 1.19

And the main.go that in the firstJob folder will refer go.mod that in the root.

The content of hello/firstJob/main.go like this as below:

  1. package main
  2. import (
  3. "log"
  4. "github.com/caarlos0/env"
  5. "github.com/demo/first-sub-project/application"
  6. )
  7. func main() {
  8. cfg := application.Config{}
  9. err := env.Parse(&cfg)
  10. if err != nil {
  11. log.Fatalf("parse config error: %v", err)
  12. }
  13. log.Println("Finish")
  14. }

I have the docker file as follows:

  1. # refer https://github.com/GoogleCloudPlatform/cloud-run-hello/blob/master/placeholder.dockerfile
  2. FROM golang:1.19-buster as builder
  3. WORKDIR /app
  4. COPY go.mod go.sum ./
  5. RUN go mod download
  6. COPY . ./
  7. RUN go build -o job github.com/demo/first-sub-project/hello/firstJob
  8. FROM alpine:3
  9. RUN apk add --no-cache ca-certificates
  10. COPY --from=builder /app/job /job
  11. ENV TZ=Asia/Tokyo
  12. ENTRYPOINT ["/job"]

I can build and push image container to the google cloud and create job on the google cloud successfully.

But when I run the job, it will show error message as below:

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

And it will working fine if I change my hello/firstJob/main.go like this as below:

  1. package main
  2. import (
  3. "log"
  4. "github.com/caarlos0/env"
  5. )
  6. type Config struct {
  7. Port int
  8. }
  9. func main() {
  10. cfg := Config{}
  11. err := env.Parse(&cfg)
  12. if err != nil {
  13. log.Fatalf("parse config error: %v", err)
  14. }
  15. log.Println("Finish")
  16. }

It seems like that it can not find the package path in the previous stage when run ENTRYPOINT in the dockerfile.

How can I fix this problem?

答案1

得分: 1

问题解决了!

就像David Maze所说的那样,问题出在不同版本的stage上。

原始的Dockerfile如下:

  1. FROM golang:1.19-buster as builder
  2. ...
  3. FROM alpine:3
  4. ...

我尝试使用不同的stage来构建项目和运行项目。

在我将Dockerfile更改为使用相同的stage来构建项目和运行项目之后,问题得到了解决。

  1. FROM golang:1.19-alpine as builder
  2. ...
  3. FROM alpine:3
  4. ...
英文:

The issue solved!

Like David Maze said, the problem is the different version of stage.

The original docker file as follows:

  1. FROM golang:1.19-buster as builder
  2. ...
  3. FROM alpine:3
  4. ...

I try to use different stages to build project and run project.

And the problem was solved after I change Dockerfile to use same stage to build project and run project.

  1. FROM golang:1.19-alpine as builder
  2. ...
  3. FROM alpine:3
  4. ...

huangapple
  • 本文由 发表于 2022年11月16日 11:43:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/74454871.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定