我构建了我的容器映像,但是当我尝试gcloud
从命令行或 Cloud Console 部署它时,我收到以下错误:“容器无法启动。无法启动然后侦听 PORT 环境变量定义的端口。 "
4 回答
在您的代码中,您可能没有侦听传入的 HTTP 请求,或者您正在侦听错误端口上的传入请求。
如Cloud Run 容器运行时合同$PORT
中所述,您的容器必须在由 Cloud Run 定义并在环境变量中提供的端口上侦听传入的 HTTP 请求。
如果您的容器未能在预期的端口上侦听,则修订健康检查将失败,修订将处于错误状态并且流量将不会路由到它。
例如,在带有 Express 的 Node.js 中,您应该使用:
const port = process.env.PORT || 8080;
app.listen(port, () => {
console.log('Hello world listening on port', port);
});
在围棋中:
port := os.Getenv("PORT")
if port == "" {
port = "8080"
}
log.Fatal(http.ListenAndServe(fmt.Sprintf(":%s", port), nil))
另一个原因之一可能是我观察到的原因。Docker 映像可能没有运行应用程序所需的代码。
我有一个用 TypeScript 编写的 Node 应用程序。为了对应用程序进行 docker 化,我需要做的就是编译代码tsc
并运行docker build
,但我虽然 gcloud 构建提交会处理这个问题,并根据 .dockerignore 建议的 Dockerfile 选择编译后的代码,并将构建我的源代码代码并提交到存储库。
但它所做的只是复制我的源代码并提交到 Cloud Build,然后根据 Dockerfile,它对我的源代码进行 docker 化,而不是对已编译的代码进行 docker 化。
因此,如果您使用需要编译的语言编写源代码,请记住在 Dockerfile 中包含构建步骤。
- 请记住,每次您将映像推送到存储库时,启用 Dockerfile 中的构建步骤都会增加映像大小。它正在吞噬那里的空间,谷歌会为此向你收费。
另一种可能性是 docker 映像以需要时间才能完成的命令结束。到部署开始时,服务器尚未运行,运行状况检查将变为空白。
那会是什么命令?通常是在开发模式下运行服务器的任何命令。对于 Scala/SBT 它将是sbt run
或在 Node 中它会类似于npm run dev
. 简而言之,请确保仅在打包的版本上运行。
Cloud Run 正在生成默认 yaml 文件,其中包含硬编码的默认端口:
spec:
containerConcurrency: 80
timeoutSeconds: 300
containers:
- image: us.gcr.io/project-test/express-image:1.0
ports:
- name: http1
containerPort: 8080
resources:
limits:
memory: 256Mi
cpu: 1000m
因此,我们需要暴露相同的 8080 端口或更改yaml 文件中的containerPort并重新部署。