英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论