我有golang制作的子项目。
我想把它构建到图像中,并上传到谷歌云的工件注册表。
所以我可以用这个图像来创建作业,并在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文件夹中会引用go。
hello/firstJob/main的内容。如下所示:
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")
}
我有docker文件如下:
# 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"]
我可以构建和推送图像容器到谷歌云,并成功地在谷歌云上创建作业。
但是当我运行作业时,它会显示如下错误信息:
standard_init_linux。go:228: exec用户进程导致:没有这样的文件或目录
如果我改变我的hello/firstJob/main,它会工作得很好。如下所示:
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时,好像找不到上一阶段的包路径
如何解决这个问题?
问题解决!
就像David Maze说的,问题在于舞台的不同版本。
docker的原始文件如下:
FROM golang:1.19-buster as builder
...
FROM alpine:3
...
我尝试用不同的阶段来构建项目和运行项目。
在我将Dockerfile改为使用同一阶段来构建项目和运行项目后,问题得到了解决。
FROM golang:1.19-alpine as builder
...
FROM alpine:3
...