【问题标题】:Cloud Run: "Failed to start and then listen on the port defined by the PORT environment variable." When I use 8080Cloud Run:“无法启动并监听 PORT 环境变量定义的端口。”当我使用 8080
【发布时间】:2021-05-13 14:41:06
【问题描述】:

当我尝试在 Google Cloud Run 中运行我的容器时,我收到了this error message

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

【问题讨论】:

  • 使用所有详细信息编辑您的问题。链接更改、中断并被删除。链接的内容将来可能会发生变化。可以包含链接作为附加参考,但您必须在问题中包含所有内容。
  • 您在 Cloud Logging 中的日志是什么?
  • @guillaumeblaquiere 在这里看到我的第一条评论:github.com/fodorpapbalazsdev/ssr-app/issues/1
  • 您找到解决此问题的方法了吗?我也遇到了同样的问题,希望有任何帮助!
  • @BalázsFodor-Pap 你修好了吗?如果有人回答了您的问题,请接受答案。

标签: google-cloud-platform dockerfile nuxt.js google-cloud-run


【解决方案1】:

只是检查一下,您使用的是 M1 Macbook 吗?在面对这个问题一段时间后,我为自己找到了一个解决方案,可能不是你的解决方案,只是为了分享我为其他 MacBook 用户找到的一些见解。

tl;博士

在将映像部署到 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。经过一番挖掘,发生这种情况的原因之一是我们试图在不同的主机平台上运行 arm64 映像(基于 M1 MacBook)。

GCP 确实在此 page 上提到了 Executables in the container image must be compiled for Linux 64-bit. Cloud Run specifically supports the Linux x86_64 ABI format.

我想这解释了为什么在 Cloud Build 上构建图像可以从这篇文章的其他答案中起作用。

【讨论】:

    【解决方案2】:

    附加的日志似乎表明您的入口点可能格式不正确。

    无法创建初始化进程:无法加载/usr/local/bin/docker-entrypoint.sh: exec format error",

    是否有任何命令或参数指定为输入?您是否可以将云运行实例的完整 yaml 放在您的 repo、gist 或 this question 中?

    【讨论】:

    【解决方案3】:

    您只在 Dockerfile 上配置了一个环境变量,但您的程序没有使用它。 By default,您的应用仍在查看 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:github.com/fodorpapbalazsdev/ssr-app/blob/… 它不能解决问题。我只是想知道,为什么我的应用程序在本地运行以及为什么我能够打开 localhost:8080(使用 'docker run -d -p 8080:8080 imageid'),如果它不能在 Cloud Run 上运行?
    • @BalázsFodor-Pap 我同意。我也想知道,因为它似乎在 Docker 和 Cloud Run 上运行良好(在 master 和包含我的解决方案的分支上)虽然我必须在依赖项上添加 '@nuxt/typescript-build' 来构建图像.您确定我们的代码与您正在测试的代码相似吗?访问 Cloud Run URL 时,我可以看到 Nuxt.js 徽标。
    • 是的,我几乎 100% 确定我使用的是相同的代码、相同的图像。 (但也许我错过了一些东西,因为我是这些技术的新手)我在这里放了一些截图:github.com/fodorpapbalazsdev/ssr-app/issues/…
    【解决方案4】:

    正如您在 Dockerfile 中看到的 node:10 官方图像 https://github.com/nodejs/docker-node/blob/4ab6ab7d06845aa950054ec5522fe8b81927bf05/10/alpine3.10/Dockerfile 一样,它们不公开任何端口。只要您没有将任何内容更改为 ENTRYPOINT,我怀疑您将 EXPOSE 8080 添加到您的 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
    EXPOSE 8080
    CMD npm start
    

    更新

    由于这个问题看起来很奇怪,所以我加倍努力并使用构建管道快速设置了您的 repo 副本,并且一切正常。 在这里您可以访问您的应用程序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'
    

    【讨论】:

    • EXPOSE 对 Cloud Run 容器没有影响。这只是 Cloud Run 中的评论。
    • @BalázsFodor-Pap 此答案的更新是否解决了您的问题?您可以按照此文档 cloud.google.com/cloud-build/docs/running-builds/… 手动执行配置
    • 如果您查看我的更新,我已删除 EXPOSE,因为它在云运行中无关紧要。我已经获取了您的存储库并设置了构建管道,我面临的唯一问题是删除 -only=production 因为它无法构建。在我构建了您的容器后,它在 Cloud Run 上运行良好。
    • 我已经设置了 Cloud Build,并且只要连接到项目的存储库发生更改,此 Cloud Build 就会构建您的映像。所以我不确定问题出在哪里,但使用 Cloud Build 构建映像并将其部署到 Cloud Run 证明工作正常,并且您的代码没有问题。总而言之,cloudbuild.yaml 是在告诉 cloud build 如何构建和部署您的容器。
    • 通过引入 Cloud Build,您将解决您的问题并引入 CD/CI 工具,这总是一件好事。
    猜你喜欢
    • 2021-11-10
    • 2021-10-07
    • 2021-11-10
    • 2022-12-01
    • 2019-09-03
    • 2021-07-26
    • 2021-05-24
    • 2022-01-12
    • 2023-01-26
    相关资源
    最近更新 更多