在Web开发中,容器是一种常见的技术,如Docker、Kubernetes等。它们能够提供环境隔离和资源管理的功能,使应用程序能够在不同的环境中运行。然而,有时候我们希望容器运行完毕后能够自动退出,而不是一直保持运行状态。那么,如何实现容器运行完毕后自动退出呢?本文将为大家介绍一些实现方法和技巧。
我的 golang fiber 服务器在 google cloud run 上运行时会自动退出并显示以下消息:
container called exit(0).
我使用以下 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"]
和我的 main.go(仅 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") }
最后一行在 google cloud run 日志中执行正常,我可以看到 api 开始侦听端口 8080
。
为什么我的容器单独退出?它应该启动 fiber api。
我发现了这个问题。在我的 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("An error happened while running the api: %s", errApp) } else { log.Printf("Api started listening in port %s", c.Port) }
并采取相应行动。
以上是容器运行完后退出的详细内容。更多信息请关注PHP中文网其他相关文章!