我构建了容器映像,但是当我尝试从gcloud
命令行或Cloud Console部署它时,出现以下错误:“容器无法启动。无法启动,然后在端口由PORT环境变量定义。”
答案 0 :(得分:1)
在您的代码中,您可能未在侦听传入的HTTP请求,或者正在侦听错误端口上的传入请求。
如Cloud Run container runtime contract中所述,您的容器必须在Cloud Run定义并在$PORT
环境变量中提供的端口上侦听传入的HTTP请求。
如果您的容器无法在预期的端口上侦听,则修订运行状况检查将失败,修订将处于错误状态,并且流量将不会路由到该状态。
例如,在带有Express的Node.js中,您应该使用:
const port = process.env.PORT || 8080;
app.listen(port, () => {
console.log('Hello world listening on port', port);
});
在Go中:
port := os.Getenv("PORT")
if port == "" {
port = "8080"
}
log.Fatal(http.ListenAndServe(fmt.Sprintf(":%s", port), nil))
答案 1 :(得分:0)
其他原因可能是我观察到docker image可能没有运行应用程序所需的代码的原因。
我有一个用打字稿编写的节点应用程序。为了对应用程序进行Docker化,我所需要做的就是编译代码tsc
并运行docker build
,但是尽管我使用gcloud构建的commit会负责这一点,并选择编译后的代码作为dokerfile中的建议与.dokerignore结合使用,并将构建我的源代码并提交到存储库。
但是它所做的就是将我的源代码复制并提交到云构建中,并且根据docker文件,它对我的源代码进行了docker处理,而不是对已编译的代码进行了Docker处理。
因此,如果要使用需要编译的语言编写源代码,请记住在docker文件中包括一个构建步骤。
答案 2 :(得分:0)
另一种可能性是,docker映像以需要一定时间才能完成的命令结束。部署开始时,服务器尚未运行,运行状况检查将变为空白。
那是什么样的命令?通常,任何以dev模式运行服务器的命令。对于Scala / SBT,它应该是sbt run
,或者在Node中,它应该像npm run dev
。简而言之,请确保仅在打包的版本上运行。
答案 3 :(得分:0)
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并重新部署。