Cloud Run:“在使用8080端口时,无法启动并侦听由PORT环境变量定义的端口。”

33

当我尝试在Google Cloud Run中运行我的容器时,出现了这个错误信息

type: Ready
status: 'False'
reason: HealthCheckContainerError
message: |-
Cloud Run error: Container failed to start. Failed to start and then listen on the port defined by the PORT environment variable. Logs for this revision might contain more information.

我已经检查了以下内容,但是没有任何帮助:

我的容器在本地运行,并且使用默认端口8080和配置为0.0.0.0的主机进行监听。

我的 Dockerfile:

FROM node:10

WORKDIR /usr/src/app

ENV PORT 8080
ENV HOST 0.0.0.0

COPY package*.json ./

RUN npm install --only=production

COPY . .

RUN npm run build

CMD npm start

有什么想法是为什么Cloud Run无法在端口上进行侦听?
项目 GitHub 仓库:

https://github.com/fodorpapbalazsdev/ssr-app


2
请编辑您的问题并提供所有细节。链接会更改、中断和删除。链接的内容可能在未来发生变化。包含链接作为附加参考是可以的,但您必须在问题中包含所有内容。 - John Hanley
你在云日志中的日志是什么? - guillaume blaquiere
@guillaumeblaquiere 请看我在这里的第一条评论:https://github.com/fodorpapbalazsdev/ssr-app/issues/1 - Balázs Fodor-Pap
你找到这个问题的解决方案了吗?我也遇到了同样的问题,如果有任何帮助,将不胜感激! - raphael_mav
我遇到了相同的问题,但我还没有找到解决方案。当我尝试将包含基于Nginx的静态Web项目的图像文件转换为服务时,我遇到了这个问题。你找到解决方案了吗? - Enes Korkmaz
看看 @Bk Lim 的回答,那是对我有用的解决方案。 - Balázs Fodor-Pap
4个回答

137

请问您使用的是 M1 MacBook 吗?我在遇到这个问题一段时间后为自己找到了解决方案,也许不适用于您,但我想分享一些我为其他 MacBook 用户找到的见解。

简而言之:

在将图像部署到 Cloud Run 之前,使用 --platform linux/amd64 标志构建 Docker 容器。

========================================================

详细说明:

除了 container failed to start and listen to the $PORT 错误外,我的日志还显示了以下内容:Application failed to start: Failed to create init process: failed to load /usr/local/bin/npm: exec format error。经过一些调查,发现其中一个原因是我们正在尝试在不同的主机平台上运行由 M1 MacBook 构建的 arm64 图像。

GCP 在此页面中提到:“容器映像中的可执行文件必须针对 Linux 64 位进行编译。Cloud Run 特别支持 Linux x86_64 ABI 格式。”

我想这就解释了为什么在此帖子中其他答案中在 Cloud Build 上构建图像会起作用。


6
这个命令对我有用。完整命令如下:docker buildx build --platform linux/amd64 -t image-name:v0.1.0 . 参考文献:Docker官方文档 - deadbyte
4
在经历了比我愿意承认的更多时间浪费后,这解决了我的问题。非常感谢你。 - Jason Dark
1
谢谢,这个方法在我的 M1 上也起作用了。顺便说一下,你应该更新你关于“本帖中的另一个答案”的引用。 - vault
1
这对我有用。我喜欢stackoverflow。非常感谢你。祝贺最近得到新笔记本电脑的每个人。 - Canovice
3
docker buildx build --platform linux/amd64 -t TAG_NAME . - rezan21
显示剩余5条评论

0

正如您可以在node:10官方映像的Dockerfile中看到https://github.com/nodejs/docker-node/blob/4ab6ab7d06845aa950054ec5522fe8b81927bf05/10/alpine3.10/Dockerfile,他们没有公开任何端口。只要您不更改ENTRYPOINT,我建议您在Dockerfile中添加EXPOSE 8080并且应该可以工作。

FROM node:10

WORKDIR /usr/src/app

ENV PORT 8080
ENV HOST 0.0.0.0

COPY package*.json ./

RUN npm install --only=production

COPY . .

RUN npm run build
EXPOSE 8080
CMD npm start

更新

由于问题看起来相当奇怪,我走了一步额外的路程,并快速设置了一个包含构建流水线的您的存储库副本,一切都正常工作。 在这里,您可以访问您的应用程序https://testssr-6dl3hr2riq-uc.a.run.app/

Dockerfile

FROM node:10

WORKDIR /usr/src/app

ENV PORT 8080
ENV HOST 0.0.0.0

COPY package*.json ./

RUN npm install 

COPY . .

RUN npm run build

CMD npm start

cloudbuild.yaml

steps:
- name: 'gcr.io/cloud-builders/docker'
  entrypoint: 'bash'
  args: ['-c','docker build --no-cache -t gcr.io/$PROJECT_ID/testssr:$SHORT_SHA .']
- name: 'gcr.io/cloud-builders/docker'
  args: ['push','gcr.io/$PROJECT_ID/testssr:$SHORT_SHA']
- name: 'gcr.io/cloud-builders/gcloud'
  args:
    - 'beta'
    - 'run'
    - 'deploy'
    - 'testssr'
    - '--image=gcr.io/$PROJECT_ID/testssr:$SHORT_SHA'
    - '--region=us-central1'
    - '--platform=managed'

1
EXPOSE 在 Cloud Run 容器中没有任何作用,它只是一个注释。 - John Hanley
@BalázsFodor-Pap,这个答案的更新是否解决了您的问题?您可以按照此文档 https://cloud.google.com/cloud-build/docs/running-builds/start-build-manually 手动执行配置。 - Donnald Cucharo
1
如果您查看我的更新,我已经删除了EXPOSE,因为在Cloud Run中它并不重要。我已经拿到了您的repo并设置了构建流水线,唯一的问题是我遇到了删除“—only=production”时构建失败的情况。在我构建了您的容器之后,它在Cloud Run上运行得非常好。 - Maciej Perliński
1
我已经设置了Cloud Build,这个云构建在你连接到项目的代码库中进行更改时构建你的镜像。所以我不确定问题出在哪里,但使用Cloud Build构建镜像并将其部署到Cloud Run似乎运行良好,你的代码没有问题。总之,cloudbuild.yaml告诉云构建如何构建和部署你的容器。 - Maciej Perliński
1
通过引入Cloud Build,您将解决问题并引入CD/CI工具,这总是一件好事。 - Maciej Perliński
显示剩余2条评论

0

你只在 Dockerfile 中配置了一个环境变量,但是你的程序并没有使用它。默认情况下,你的应用仍然会访问 localhost:3000

要解决这个问题,请前往你的 nuxt.config.js 文件,并像这样添加 server 配置:

export default {
  // Global page headers: https://go.nuxtjs.dev/config-head
  server: {
    port: process.env.PORT, // default: 3000
    host: process.env.HOST  // default: localhost
  },
  head: {
    title: 'ssr-app',
    htmlAttrs: {
      lang: 'en'
    },

    ...
}

之后,重新构建容器并将新版本部署到Cloud Run。


我按照你的建议编辑了nuxt.config.js: https://github.com/fodorpapbalazsdev/ssr-app/blob/98716b099d74ff898832fe228fdd3fa52d92a334/nuxt.config.js#L3 但这并没有解决问题。我很好奇,为什么我的应用程序在本地运行,并且我能够打开localhost:8080(使用“docker run -d -p 8080:8080 imageid”),如果它在Cloud Run上无法工作? - Balázs Fodor-Pap
@BalázsFodor-Pap 我同意。我也在想,因为它似乎在 Docker 上和 Cloud Run 上都运行良好(无论是在主分支还是包含我的解决方案的分支上),尽管我不得不在依赖项中添加 '@nuxt/typescript-build' 来构建镜像。你确定我们的代码与你正在测试的代码类似吗?当访问 Cloud Run URL 时,我可以看到 Nuxt.js 的标志。 - Donnald Cucharo
是的,我几乎可以确定我正在使用相同的代码和相同的图像。(但也许我错过了什么,因为我对这些技术还很陌生)我在这里放了一些截图:https://github.com/fodorpapbalazsdev/ssr-app/issues/1#issuecomment-776661398 - Balázs Fodor-Pap

0

附上的日志似乎显示您的入口点可能格式错误。

无法创建初始化进程:无法加载 /usr/local/bin/docker-entrypoint.sh:执行格式错误。

是否有指定输入的命令或参数?您是否可以将完整的云运行实例的 yaml 放在您的存储库、gist 或此问题中?

Cloud Console


你可以在这里找到我的YAML文件: https://github.com/fodorpapbalazsdev/ssr-app/issues/1 - Balázs Fodor-Pap
我注意到您正在本地浏览“localhost:8080”。如果您浏览“0.0.0.0:8080”,是否可以正常工作?Localhost可能会绑定到“127.0.0.1:8080”。https://cloud.google.com/run/docs/troubleshooting#listen_address - Chris Wilcox
1
是的,'0.0.0.0:8080' 也可以在本地工作。 - Balázs Fodor-Pap

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接