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

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

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

问题

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

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

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

项目的结构如下所示:

├ application
│
├ hello
│ └ firstJob
│    └ main.go
│
├ go.mod
│
├ go.sum
│
└ main.go

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

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

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

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

package main

import (
	"log"

	"github.com/caarlos0/env"
	"github.com/demo/first-sub-project/application"
)

func main() {
	cfg := application.Config{}
	err := env.Parse(&cfg)
	if err != nil {
		log.Fatalf("parse config error: %v", err)
	}
	log.Println("Finish")
}

我有以下Dockerfile:

# 参考 https://github.com/GoogleCloudPlatform/cloud-run-hello/blob/master/placeholder.dockerfile
FROM golang:1.19-buster as builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . ./
RUN go build -o job github.com/demo/first-sub-project/hello/firstJob

FROM alpine:3
RUN apk add --no-cache ca-certificates
COPY --from=builder /app/job /job
ENV TZ=Asia/Tokyo
ENTRYPOINT ["/job"]

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

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

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

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

package main

import (
	"log"

	"github.com/caarlos0/env"
)

type Config struct {
    Port int
}

func main() {
	cfg := Config{}
	err := env.Parse(&cfg)
	if err != nil {
		log.Fatalf("parse config error: %v", err)
	}
	log.Println("Finish")
}

似乎在运行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:

├ application
│
├ hello
│ └ firstJob
│    └ main.go
│
├ go.mod
│
├ go.sum
│
└ main.go

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

module github.com/demo/first-sub-project
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:

package main

import (
	"log"

	"github.com/caarlos0/env"
	"github.com/demo/first-sub-project/application"
)

func main() {
	cfg := application.Config{}
	err := env.Parse(&cfg)
	if err != nil {
		log.Fatalf("parse config error: %v", err)
	}
	log.Println("Finish")
}

I have the docker file as follows:

# refer https://github.com/GoogleCloudPlatform/cloud-run-hello/blob/master/placeholder.dockerfile
FROM golang:1.19-buster as builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . ./
RUN go build -o job github.com/demo/first-sub-project/hello/firstJob

FROM alpine:3
RUN apk add --no-cache ca-certificates
COPY --from=builder /app/job /job
ENV TZ=Asia/Tokyo
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:

package main

import (
	"log"

	"github.com/caarlos0/env"
)

type Config struct {
    Port int
}

func main() {
	cfg := Config{}
	err := env.Parse(&cfg)
	if err != nil {
		log.Fatalf("parse config error: %v", err)
	}
	log.Println("Finish")
}

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如下:

FROM golang:1.19-buster as builder
...

FROM alpine:3
...

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

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

FROM golang:1.19-alpine as builder
...

FROM alpine:3
...
英文:

The issue solved!

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

The original docker file as follows:

FROM golang:1.19-buster as builder
...

FROM alpine:3
...

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.

FROM golang:1.19-alpine as builder
...

FROM alpine:3
...

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:

确定