在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)
}
并采取相应行动。
以上就是容器运行完后退出的详细内容,更多请关注编程网其它相关文章!