容器在运行后退出。

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

Container exits after running after running

问题

我有一个 Golang Fiber 服务器,在 Google Cloud Run 上运行时会自动退出,并显示以下消息:

Container called exit(0).

我使用以下 Dockerfile 运行它:

# 使用官方的 golang 镜像创建二进制文件。
FROM golang:buster as builder

# 创建并切换到应用目录。
WORKDIR /app

# 获取应用程序的依赖项。
COPY go.mod ./
COPY go.sum ./
RUN go mod download

COPY . ./
RUN go build

# 使用官方的 Debian slim 镜像创建精简的生产容器。
# https://hub.docker.com/_/debian
# https://docs.docker.com/develop/develop-images/multistage-build/#use-multi-stage- builds
FROM debian:buster-slim
RUN set -x && apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y \
    ca-certificates && \
    rm -rf /var/lib/apt/lists/*

# 从构建阶段将二进制文件复制到生产镜像。
COPY --from=builder /app/redirect-middleware.git /app/
COPY --from=builder /app/pkg /app/pkg/

EXPOSE 8080

# 在容器启动时运行 Web 服务。
CMD ["/app/redirect-middleware.git", "dev"]

以及我的 main.go(只有 func main())

func main() {
    // 加载环境配置
    c, err := config.LoadConfig()
    if err != nil {
        log.Fatalln("Failed at config", err)
    }

    // 初始化数据库
    db.InitDb()

    // 初始化 Fiber API
    app := fiber.New()
    log.Print("Started new Fiber app...")

    // 初始化路由,发送 API 的版本
    app.Get("/", func(c *fiber.Ctx) error {
        return c.SendString(fmt.Sprintf("Redirection middleware - v%s", viper.Get("Version").(string)))
    })
    log.Print("Default root route set...")

    // API 路由
    api := app.Group("/api") // /api
    v1 := api.Group("/v1") // /api/v1
    log.Print("api/v1 group set...")

    // 注册 v1 路由
    mastermenus.RegisterRoutes(v1)
    log.Print("Route registered...")

    app.Listen(c.Port)
    log.Print("Api started listening in port 8080")
}

在 Google Cloud Run 日志中,最后一行执行正常,我可以看到 Api started listening in port 8080

为什么我的容器会自动退出?它应该启动 Fiber API。

英文:

I have a Golang Fiber server that exits automatically with the following message when running on Google Cloud Run:

Container called exit(0).

I am running it with the following Dockerfile

# Use the offical golang image to create a binary.
FROM golang:buster as builder

# Create and change to the app directory.
WORKDIR /app

# Retrieve application dependencies.
COPY go.mod ./
COPY go.sum ./
RUN go mod download

COPY . ./
RUN go build

# Use the official Debian slim image for a lean production container.
# https://hub.docker.com/_/debian
# https://docs.docker.com/develop/develop-images/multistage-build/#use-multi-stage- builds
FROM debian:buster-slim
RUN set -x && apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y \
    ca-certificates && \
    rm -rf /var/lib/apt/lists/*

# Copy the binary to the production image from the builder stage.
COPY --from=builder /app/redirect-middleware.git /app/
COPY --from=builder /app/pkg /app/pkg/

EXPOSE 8080

# Run the web service on container startup.
CMD ["/app/redirect-middleware.git", "dev"]

and my main.go (only func main())

func main() {
    // Load env config
	c, err := config.LoadConfig()
    if err != nil {
	    log.Fatalln("Failed at config", err)
	}

    // init DB
	db.InitDb()

    // init fiber API
	app := fiber.New()
    log.Print("Started new Fiber app...")

	// initial route sending version of API
    app.Get("/", func(c *fiber.Ctx) error {
	    return c.SendString(fmt.Sprintf("Redirection middleware - v%s", viper.Get("Version").(string)))
    })
	log.Print("Default root route set...")

    // api routes
	api := app.Group("/api") // /api
    v1 := api.Group("/v1") // /api/v1
	log.Print("api/v1 group set...")

    // register routes v1
	mastermenus.RegisterRoutes(v1)
    log.Print("Route registered...")

	app.Listen(c.Port)
    log.Print("Api started listening in port 8080")
}

The last line is executing fine in Google Cloud Run logs, I can see the Api started listening in port 8080.

Why is my container exiting alone? It should start the Fiber API.

答案1

得分: 0

我找到了问题。在我的 stage.env 文件中,我设置了端口为 :8080
在本地环境中,将 app.Listen(c.Port) 传递给 app.Listen(":8080") 可以正常工作。但是在使用 Cloud Run 时,它会被转换为 app.Listen("8080"),这当然不起作用,因为它认为这是一个主机而不是一个端口。

我添加了 app.Listen(":" + c.Port),这样就可以正常工作了。

如果你遇到这个问题,请捕获错误:

errApp := app.Listen(":" + c.Port)
if errApp != nil {
    log.Printf("在运行 API 时发生错误%s", errApp)
} else {
	log.Printf("API 开始监听端口 %s", c.Port)
}

然后根据情况采取相应的措施。

英文:

I found the issue. In my stage.env file I have setup the port to be :8080.
Locally, passing app.Listen(c.Port) translates fine to app.Listen(":8080") as expected. When using that in Cloud Run this is transformed to app.Listen("8080"), which of course does not work as it thinks this is a host and not a port.

I added app.Listen(":" + c.Port) which works.

In case you experience that, please catch the error:

errApp := app.Listen(":" + c.Port)
if errApp != nil {
    log.Printf("An error happened while running the api: %s", errApp)
} else {
	log.Printf("Api started listening in port %s", c.Port)
}

And act accordingly.

huangapple
  • 本文由 发表于 2023年3月21日 18:40:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/75800135.html
匿名

发表评论

匿名网友

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

确定