从源代码部署服务

本页面介绍了如何使用单个 gcloud CLI 命令(带有 --source 标志的 gcloud run deploy)直接从源代码将新服务或服务修订版本部署到 Cloud Run。如需查看部署 Hello World 服务的示例演示,请参阅从源代码部署快速入门

您可以通过以下两种不同的方式使用此功能:

请注意,源部署使用 Artifact Registry 来存储构建的容器。如果您的项目在您要部署到的区域中还没有名为 cloud-run-source-deploy 的 Artifact Registry 代码库,此功能会自动创建一个名为 cloud-run-source-deploy 的 Artifact Registry 代码库。

如果源代码目录中有 Dockerfile,那么上传的源代码将使用该 Dockerfile 来构建。如果源代码目录中不存在 Dockerfile,Google Cloud 的 Buildpack 会使用 Google 管理的安全基础映像,自动检测您正在使用的语言,并提取代码的依赖项,以实现可正式投入生产的容器映像。

默认情况下,安全修复程序仅在部署 Cloud Run 服务时应用。为某个服务启用自动安全更新后,该服务会自动接收补丁,而不会造成任何停机时间。详细了解如何配置安全更新

准备工作

  • 确保您已按照设置页面中的说明为 Cloud Run 设置了新项目。
  • 如果您通过网域限制组织政策来限制项目的未经身份验证的调用,则您需要按照测试专用服务中的说明访问已部署的服务。

  • Enable the Cloud Run Admin API.

    Roles required to enable APIs

    To enable APIs, you need the Service Usage Admin IAM role (roles/serviceusage.serviceUsageAdmin), which contains the serviceusage.services.enable permission. Learn how to grant roles.

    Enable the API

    启用 Cloud Run Admin API 后,系统会自动创建 Compute Engine 默认服务账号。

所需的角色

如需从源代码进行部署,您或您的管理员必须向部署者账号授予以下 IAM 角色。

点击可查看部署者账号所需的角色

如需获得从来源进行构建和部署所需的权限,请让管理员向您授予以下 IAM 角色:

如需查看与 Cloud Run 关联的 IAM 角色和权限的列表,请参阅 Cloud Run IAM 角色Cloud Run IAM 权限。如果您的 Cloud Run 服务与Google Cloud API(例如 Cloud 客户端库)进行交互,请参阅服务身份配置指南。如需详细了解如何授予角色,请参阅部署权限管理访问权限

支持的语言

除了 Dockerfile 包含的源代码之外,从源代码进行部署还支持以下语言(使用 Google Cloud 的 Buildpack):

运行时 源代码部署 Buildpack 配置
Go 部署 Go 服务 配置 Go Buildpack
Node.js 部署 Node.js 服务 配置 Node.js Buildpack
Python 部署 Python 服务 配置 Python Buildpack
Java
(包括 Kotlin、Groovy、Scala)
部署 Java 服务 配置 Java Buildpack
.NET 部署 .NET 服务 配置 .NET Buildpack
Ruby 部署 Ruby 服务 配置 Ruby Buildpack
PHP 部署 PHP 服务 配置 PHP Buildpack

详细了解支持的语言版本

从源代码部署并进行构建

本部分介绍如何使用 Google Cloud 的 buildpack 和 Cloud Build 基于您的源代码自动构建容器映像,无需在机器上安装 Docker 或者设置 buildpack 或 Cloud Build。

限制

  • 从源代码部署时使用 Artifact Registry 和 Cloud Build,因此此功能仅在 Artifact Registry 支持的区域Cloud Build 支持的区域提供。
  • 从源代码部署是一项便捷功能,不允许对构建进行全面自定义。如需进行更多控制,请使用 Cloud Build 构建容器映像(例如,使用 gcloud builds submit),然后部署容器映像(例如,使用 gcloud run deploy --image)。
  • 使用 Google Cloud 的 buildpack 从源代码部署会将源文件的上次修改日期设置为 1980 年 1 月 1 日。这是 Buildpack 的默认行为,旨在支持可重现的 build。这可能会影响静态文件的浏览器端缓存,具体取决于您的语言框架。如果您的应用受此影响,Google 建议您在应用中停用 etagLast-Modified HTTP 标头。
  • 使用 Google Cloud 的 buildpack 从源代码部署始终使用 gcr.io/buildpacks/builder:latest。如果您的首选语言或操作系统配置在 latest 中不可用,请使用特定构建器通过首选构建器创建应用映像。
  • 您可以使用 Kotlin 和其他 JVM 语言(例如 Java)从源代码部署服务。您使用的语言必须符合以下规则:

    • 您可以使用 Maven 或 Gradle 构建应用。
    • 构建文件包含产品类所需的所有插件。

使用 build 部署之前的准备工作

在通过 build 从源代码进行部署之前:

  • 按照准备工作中的步骤操作。

  • Enable the Cloud Build API.

    Roles required to enable APIs

    To enable APIs, you need the Service Usage Admin IAM role (roles/serviceusage.serviceUsageAdmin), which contains the serviceusage.services.enable permission. Learn how to grant roles.

    Enable the API

所需的角色

如需通过 build 从源代码进行部署,您或您的管理员必须为 Cloud Build 服务账号授予以下 IAM 角色。

点击可查看 Cloud Build 服务账号需要的角色

除非您替换此行为,否则 Cloud Build 会自动使用 Compute Engine 默认服务账号作为默认 Cloud Build 服务账号来构建源代码和 Cloud Run 资源。为了让 Cloud Build 能够构建来源,请让管理员向项目的 Compute Engine 默认服务账号授予 Cloud Run Builder (roles/run.builder):

  gcloud projects add-iam-policy-binding PROJECT_ID \
      --member=serviceAccount:PROJECT_NUMBER-compute@developer.gserviceaccount.com \
      --role=roles/run.builder
  

PROJECT_NUMBER 替换为您的 Google Cloud项目编号,将 PROJECT_ID 替换为您的 Google Cloud项目 ID。如需详细了解如何查找项目 ID 和项目编号,请参阅创建和管理项目

向 Compute Engine 默认服务账号授予 Cloud Run Builder 角色需要几分钟时间才能传播

如需查看与 Cloud Run 关联的 IAM 角色和权限的列表,请参阅 Cloud Run IAM 角色Cloud Run IAM 权限。如果您的 Cloud Run 服务与Google Cloud API(例如 Cloud 客户端库)进行交互,请参阅服务身份配置指南。如需详细了解如何授予角色,请参阅部署权限管理访问权限

使用 build 进行部署

如需从源代码进行部署,请点击相应标签页即可获得有关所选工具的使用说明。

gcloud

  1. In the Google Cloud console, activate Cloud Shell.

    Activate Cloud Shell

    At the bottom of the Google Cloud console, a Cloud Shell session starts and displays a command-line prompt. Cloud Shell is a shell environment with the Google Cloud CLI already installed and with values already set for your current project. It can take a few seconds for the session to initialize.

  2. 切换到源代码目录。源目录会使用 Dockerfile(如果存在),但这不是必需的。

  3. 构建和部署服务:

    gcloud run deploy SERVICE --source .

    SERVICE 替换为您要用于服务的名称。

  4. 在系统提示时通过响应 y 来响应任何提示,以安装所需 API。您只需为项目执行一次此操作。如果您尚未按照设置页面中的说明为其他提示设置默认值,请通过提供平台和区域来响应这些提示。

  5. 等待构建和部署完成。完成后,Cloud Run 会显示一条成功消息。

  6. 部署后,此服务修订版本可处理所有流量。

    Cloud Code

    如需使用 Cloud Code 从源代码进行部署,请阅读 IntelliJVisual Studio Code 指南。

    Gemini CLI

    使用 Gemini CLI 工具中的 /deploy 命令从源代码部署 Cloud Run 服务。

    如需将 Gemini CLI 与 Cloud Run 扩展程序搭配使用,请按以下步骤操作:

    1. 在以下开发环境之一中安装最新版本的 Gemini CLI

      • 终端
      • Cloud Shell
      • VS Code 使用 Gemini Code Assist 代理模式(请参阅“VS Code”标签页)
    2. 安装 Cloud Run 扩展程序:

      gemini extensions install https://github.com/GoogleCloudPlatform/cloud-run-mcp
    3. 登录 Google Cloud 控制台。

      gcloud auth login
    4. 设置应用默认凭据

      gcloud auth application-default login
    5. 切换到源代码目录。

    6. 启动 Gemini CLI:

      gemini
    7. 构建和部署服务:

      /deploy
      • 如果系统提示您提供 Google Cloud 项目,请输入您的项目名称。
      • 如果系统提示您选择工具,请选择 deploy_local_folder
    8. 等待构建和部署完成。完成后,Cloud Run 会显示一条成功消息。

    MCP

    如需从 Model Context Protocol (MCP) 客户端的源代码部署 Cloud Run 服务,请安装 Cloud Run Model Context Protocol (MCP) 服务器

    安装说明因 MCP 客户端而异。通常,您需要将以下行添加到设置 JSON 文件中:

    "mcpServers":{
      "cloud-run": {
        "command": "npx",
        "args": ["-y", "@google-cloud/cloud-run-mcp"]
      }
    }

    写邮件

    您可以将 Compose 规范存储在 YAML 文件中,然后使用单个 gcloud 命令将其从源代码部署为 Cloud Run 服务。

    1. 切换到源代码目录。源目录会使用 Dockerfile(如果存在),但这不是必需的。

    2. 在项目目录中,创建一个包含服务定义的 compose.yaml 文件。

      services:
        web:
          build: .
          ports:
            - "8080:8080"

      您还可以指定更多配置选项,例如环境变量、Secret 和卷装载。

    3. 如需部署服务,请运行 gcloud beta run compose up 命令:

      gcloud beta run compose up compose.yaml
    4. 在系统提示时,通过响应 y 来响应任何提示,以安装所需组件或启用 API。

    5. 可选:如果您想允许对服务进行未经身份验证的访问,请将服务设为公开

    部署完成后,系统会显示 Cloud Run 服务网址。复制此网址并将其粘贴到浏览器中,即可查看正在运行的容器。您可以通过 Google Cloud 控制台停用默认身份验证。

从源代码部署,无需构建

您可以直接将源制品部署到 Cloud Run,从而跳过 Cloud Build 步骤。 这种方式的运作方式是,您可以将应用的预打包归档直接上传到 Cloud Storage 存储桶,而不是从源代码构建容器映像。然后,Cloud Run 会获取此归档文件,并直接在基础映像上运行它。这种方法可大幅缩短部署时间。

限制

部署到没有 build 的来源仅支持以下内容:

  • Cloud Run 服务。
  • 支持的运行时(不支持 Dockerfile)。
  • 源归档文件 (.tar.gz) <= 250 MiB。
  • 二进制文件(例如 Go 二进制文件)或脚本(例如 Python 脚本)必须与 x86 架构兼容。
  • 来源必须是独立的,并包含所有依赖项。运行时基础映像仅包含最少的操作系统和一些语言库。

在不进行构建的情况下部署之前

如需使用“部署但不构建”功能,请执行以下操作:

  • 确保您已完成准备工作中的步骤。
  • 启用 Cloud Run API 和 Cloud Storage API:

    gcloud services enable run.googleapis.com \
      storage.googleapis.com
    
  • 您必须在部署之前在本地安装应用依赖项,因为它们不会被安装(不会构建)。

部署但不构建

本部分介绍了如何在不使用 build 的情况下将制品直接部署到 Cloud Run。

gcloud

如需部署本地源目录,请使用 --no-build 标志告知 deploy 命令跳过 Cloud Build 步骤:

gcloud beta run deploy SERVICE_NAME \
  --source APPLICATION_PATH \
  --no-build \
  --base-image=BASE_IMAGE \
  --command=COMMAND \
  --args=ARG

替换以下内容:

  • SERVICE_NAME:Cloud Run 服务的名称。
  • APPLICATION_PATH:应用在本地文件系统中的位置。
  • BASE_IMAGE:您要用于应用的运行时基础映像。例如 us-central1-docker.pkg.dev/serverless-runtimes/google-24-full/runtimes/nodejs24
  • COMMAND:容器启动时要运行的命令。
  • ARG:您发送到容器命令的实参。如果您使用多个参数,请在各自的行中指定每个参数。

YAML

您可以将服务规范存储在 YAML 文件中,然后使用 gcloud CLI 或 Google Cloud 控制台service.yaml编辑器进行部署。

  1. 创建一个存储桶来存放您的应用:

    gcloud storage buckets create gs://BUCKET_NAME --location=BUCKET_LOCATION
    

    替换以下内容:

    • BUCKET_NAME:您要为存储桶指定的名称(须遵循命名要求)。例如 my-bucket
    • BUCKET_LOCATION:存储桶的位置。例如 US
  2. 使用 zip 或 tar 创建包含应用源代码的归档文件,例如:

    tar -cvzf ARCHIVE_NAME APPLICATION_PATH
    

    替换以下内容:

    • ARCHIVE_NAME:要创建的归档的名称。例如 app.tar.gz
    • APPLICATION_PATH:应用在本地文件系统中的位置。例如 ~/my-application。 如需归档当前工作目录,请将此值设置为 *
  3. 将应用归档文件上传到 Cloud Storage:

    gcloud storage cp ARCHIVE_NAME gs://BUCKET_NAME
    

    替换以下内容:

    • ARCHIVE_NAME:您之前创建的归档文件的本地路径。例如 app.tar.gz
    • BUCKET_NAME:您之前创建的存储桶的名称。例如 my-bucket
  4. 创建包含以下内容的新 service.yaml 文件:

    apiVersion: serving.knative.dev/v2
    kind: Service
    metadata:
     name: SERVICE_NAME
    spec:
     template:
       metadata:
         annotations:
           run.googleapis.com/sources: '{"": "gs://BUCKET_NAME/ARCHIVE_NAME"}'
           run.googleapis.com/base-images: '{"": "BASE_IMAGE"}'
       spec:
         containers:
         - image: scratch
           command:
           - COMMAND
           args:
           - ARG1
           - ARG-N
         runtimeClassName: run.googleapis.com/linux-base-image-update
    

    替换以下内容:

    • SERVICE_NAME:Cloud Run 服务的名称。 服务名称不得超过 49 个字符,并且在每个区域和项目中必须是唯一的。
    • BUCKET_NAME:您之前创建的存储桶的名称。例如 my-bucket
    • ARCHIVE_NAME:您之前创建的归档文件的本地路径。例如 app.tar.gz
    • BASE_IMAGE:您要用于应用的基础运行时映像。例如 us-central1-docker.pkg.dev/serverless-runtimes/google-24-full/runtimes/nodejs24
    • COMMAND:容器启动时要运行的命令。
    • ARG1:要发送到容器命令的参数。 如果您使用多个参数,请在各自的行中指定每个参数,例如 ARG-N
  5. 部署新服务:

    gcloud run services replace service.yaml
    

REST API

REST API:

curl -H "Content-Type: application/json" \
-H "Authorization: Bearer ACCESS_TOKEN" \
-X POST \
-d '{"template": {"containers": [{"command": ["npm"], "args": ["start"], "image": "scratch", "baseImageUri": "google-22/nodejs22", "sourceCode": {"cloudStorageSource": {"bucket": "'GCS_BUCKET_NAME", "object":"ARCHIVE"}}}]}}' \
https://run.googleapis.com/v2/projects/PROJECT_ID/locations/REGION/services?serviceId=SERVICE_NAME

从源代码部署(无需构建)的示例

本部分举例说明了如何在不使用 build 的情况下从源代码进行部署。

Node.js

创建 Node.js 服务:

  1. 创建名为 helloworld 的新目录,并转到此目录中:

    mkdir helloworld
    cd helloworld
    
  2. 创建一个包含以下内容的 package.json 文件:

    {
      "name": "helloworld",
      "description": "Simple hello world sample in Node",
      "version": "1.0.0",
      "private": true,
      "main": "index.js",
      "type": "module",
      "scripts": {
        "start": "node index.js"
      },
      "engines": {
        "node": ">=16.0.0"
      },
      "author": "Google LLC",
      "license": "Apache-2.0",
      "dependencies": {
        "express": "^4.17.1"
      }
    }
    
  3. 在同一目录中,创建一个 index.js 文件,并将以下代码行复制到其中:

    import express from 'express';
    const app = express();
    
    app.get('/', (req, res) => {
      const name = process.env.NAME || 'World';
      res.send(`Hello ${name}!`);
    });
    
    const port = parseInt(process.env.PORT) || 8080;
    app.listen(port, () => {
      console.log(`helloworld: listening on port ${port}`);
    });

    此代码会创建一个基本 Web 服务器,以侦听由 PORT 环境变量定义的端口。

  4. helloworld 目录中,运行以下命令以在本地安装服务依赖项:

    npm install
  5. helloworld 目录中,使用 --no-build 标志部署服务,该标志会告知 deploy 命令跳过 Cloud Build 步骤:

    gcloud beta run deploy helloworld \
     --source . \
     --region=REGION \
     --no-build \
     --base-image=nodejs24 \
     --command=node \
     --args=index.js
     

    替换以下内容:

    • REGION:服务部署所在的区域。

Python

创建 Python 服务:

  1. 创建名为 helloworld 的新目录,并转到此目录中:

    mkdir helloworld
    cd helloworld
    
  2. 创建名为 main.py 的文件,并将以下代码粘贴到其中:

    import os
    
    from flask import Flask
    
    app = Flask(__name__)
    
    
    @app.route("/")
    def hello_world():
        """Example Hello World route."""
        name = os.environ.get("NAME", "World")
        return f"Hello {name}!"
    
    
    if __name__ == "__main__":
        app.run(debug=True, host="0.0.0.0", port=int(os.environ.get("PORT", 8080)))

    此代码使用我们的“Hello World”问候语响应请求。HTTP 处理由容器中的 Gunicorn Web 服务器进行。当直接调用以供本地使用时,此代码会创建一个基本 Web 服务器,该服务器侦听 PORT 环境变量定义的端口。

  3. 创建名为 requirements.txt 的文件,并将以下代码粘贴到其中:

    Flask==3.0.3
    gunicorn==23.0.0
    Werkzeug==3.0.3
    

    此代码会添加示例所需的软件包。

  4. 将依赖项纳入供应商目录:

    pip3 install -r requirements.txt --target=./vendor
    
  5. 使用 gcloud CLI 部署服务。--no-build 标志会指示 deploy 命令绕过 Cloud Build 步骤:

    gcloud beta run deploy helloworld \
      --source . \
      --region=REGION \
      --no-build \
      --base-image=python313 \
      --command=python \
      --args=main.py \
      --set-env-vars PYTHONPATH=./vendor
    

REGION 替换为您的服务部署到的区域。

问题排查

本部分提供了一些有关在不使用 build 的情况下排查从源代码部署问题的提示。

本地开发

从源代码进行部署而不使用 build 的方式与将代码或可执行文件装载到基础映像类似。

例如:

  1. 复制所有内容:

    cp -R python/hello-world/ workspace
  2. 以根用户身份运行基础映像,并挂载来源。如果您需要从主机运行 curl,可以选择添加 -p 8080:8080

    docker run -it -v "LOCAL_PATH" -u 0 us-central1-docker.pkg.dev/serverless-runtimes/google-22-full/runtimes/python313 /bin/bash`

    LOCAL_PATH 替换为本地源文件的位置。

  3. 运行服务器:

    python main.py

执行日志

执行日志有助于调试部署失败问题。在 Google Cloud 控制台中,依次前往可观测性 > 日志

Cloud Storage 访问权限被拒绝

如果您的 Cloud Run 服务在尝试访问 Cloud Storage 对象时遇到“权限遭拒”错误,您必须向 Cloud Run 服务账号授予 roles/storage.objectViewer 角色:

gcloud projects add-iam-policy-binding PROJECT \
  --member="SERVICE_ACCOUNT" \
  --role="roles/storage.objectViewer"

替换以下内容:

  • PROJECT:您的 Google Cloud 项目 ID。
  • SERVICE_ACCOUNT:您的 Cloud Run 服务账号。 例如 service-123@serverless-robot-staging.iam.gserviceaccount.com

从源代码自动构建

为了避免本地来源中发生无版本控制的更改,Google 建议您在将更改推送到 Git 代码库时自动部署。为便于操作,您可以将持续部署关联到 Cloud Run 服务并进行配置。通过将 GitHub 代码库关联到 Cloud Run,您可以配置构建和部署代码库,而无需编写 Dockerfile 或构建文件。

如需配置自动构建,请按照持续构建页面中的说明设置自动化,请务必选择使用 Buildpack 构建源代码的选项。

后续步骤

部署 Cloud Run 服务后,您可以执行以下操作:

了解源代码部署配置:

您可以使用 Cloud Build 触发器自动构建和部署 Cloud Run 服务: