了解如何将示例 Rails 应用部署到 Cloud Run 以及如何将代管式数据库、对象存储、加密的 Secret 和构建流水线与无服务器计算集成。
部署 Rails 应用涉及将多项服务集成在一起,从而形成一个整合的项目。本教程假定您熟悉 Rails Web 开发。
本教程需要 Ruby 3.0 或更高版本和 Rails 8 或更高版本。
目标
- 创建 Cloud SQL 数据库并将其连接到 Active Record
- 创建和使用 Secret Manager 安全地存储和访问 Rails 主密钥
- 通过 Active Storage 托管 Cloud Storage 上用户上传的媒体和文件
- 使用 Cloud Build 自动执行构建和数据库迁移
- 将 Rails 应用部署到 Cloud Run
费用
准备工作
- 登录您的 Google Cloud 账号。如果您是 Google Cloud新手,请 创建一个账号来评估我们的产品在实际场景中的表现。新客户还可获享 $300 赠金,用于运行、测试和部署工作负载。
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
Roles required to select or create a project
- Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
-
Create a project: To create a project, you need the Project Creator role
(
roles/resourcemanager.projectCreator), which contains theresourcemanager.projects.createpermission. Learn how to grant roles.
-
Verify that billing is enabled for your Google Cloud project.
Enable the Cloud Run, Cloud SQL, Cloud Build, Secret Manager, and Compute Engine APIs.
Roles required to enable APIs
To enable APIs, you need the Service Usage Admin IAM role (
roles/serviceusage.serviceUsageAdmin), which contains theserviceusage.services.enablepermission. Learn how to grant roles.-
安装 Google Cloud CLI。
-
如果您使用的是外部身份提供方 (IdP),则必须先使用联合身份登录 gcloud CLI。
-
如需初始化 gcloud CLI,请运行以下命令:
gcloud init -
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
Roles required to select or create a project
- Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
-
Create a project: To create a project, you need the Project Creator role
(
roles/resourcemanager.projectCreator), which contains theresourcemanager.projects.createpermission. Learn how to grant roles.
-
Verify that billing is enabled for your Google Cloud project.
Enable the Cloud Run, Cloud SQL, Cloud Build, Secret Manager, and Compute Engine APIs.
Roles required to enable APIs
To enable APIs, you need the Service Usage Admin IAM role (
roles/serviceusage.serviceUsageAdmin), which contains theserviceusage.services.enablepermission. Learn how to grant roles.-
安装 Google Cloud CLI。
-
如果您使用的是外部身份提供方 (IdP),则必须先使用联合身份登录 gcloud CLI。
-
如需初始化 gcloud CLI,请运行以下命令:
gcloud init - 确保使用于本教程的账号拥有足够的权限。
准备环境
本教程使用多种 Google Cloud 服务来提供支持已部署的 Rails 应用的数据库、媒体存储和 Secret 存储。通过配置用于部署服务的区域和克隆 Rails 应用来准备环境。
设置默认项目和区域
运行以下命令,为 gcloud CLI 设置默认项目配置:
gcloud config set project PROJECT_ID将
PROJECT_ID替换为您的 Google Cloud项目 ID配置区域:
export REGION=REGION将
REGION替换为相应的位置。为了提高服务之间的效率,所有服务都应部署在同一区域中。如需详细了解离您最近的区域,请参阅各位置可使用的产品。
克隆 Rails 应用
Rails 示例应用的代码位于 GitHub 上的 GoogleCloudPlatform/ruby-docs-samples 代码库中。
克隆代码库:
git clone https://github.com/GoogleCloudPlatform/ruby-docs-samples.git转到包含示例代码的目录并运行以下命令,以确保已使用所需的 gem 和依赖项正确设置应用:
Linux/macOS
cd ruby-docs-samples/run/rails bundle installWindows
cd ruby-docs-samples\run\rails bundle install
准备支持性服务
本教程使用多种 Google Cloud 服务来提供支持已部署的 Rails 项目的数据库、媒体存储和 Secret 存储。这些服务部署在特定区域。为了提高服务之间的效率,最好将所有服务部署在同一区域中。如需详细了解离您最近的区域,请参阅各位置可使用的产品。
设置 Cloud SQL for PostgreSQL 实例
Rails 支持多种关系型数据库,包括 Cloud SQL 提供的多个关系型数据库。本教程使用 PostgreSQL,这是一个 Rails 应用常用的开源数据库。
以下部分介绍了如何为 Rails 应用创建 PostgreSQL 实例、数据库和数据库用户。
创建 PostgreSQL 实例
控制台
在 Google Cloud 控制台中,前往 Cloud SQL 实例页面。
点击创建实例。
点击选择 PostgreSQL。
在实例 ID 字段中,输入实例的名称 (
INSTANCE_NAME)。在密码字段中,输入 postgres 用户的密码。
对于其他字段,请使用默认值。
点击创建实例。
gcloud
创建 PostgreSQL 实例:
gcloud sql instances create INSTANCE_NAME \ --database-version POSTGRES_12 \ --tier db-f1-micro \ --region REGION替换以下内容:
INSTANCE_NAME:新的 Cloud SQL 实例名称REGION:Google Cloud 区域
创建实例并准备好使用需要几分钟时间。
创建数据库
控制台
在 Google Cloud 控制台中,前往 Cloud SQL 实例页面。
选择 INSTANCE_NAME 实例。
转到数据库标签页。
点击创建数据库。
在数据库名称对话框中,输入
DATABASE_NAME。点击创建。
gcloud
在最近创建的实例中创建数据库:
gcloud sql databases create DATABASE_NAME \ --instance INSTANCE_NAME将
DATABASE_NAME替换为实例中数据库的名称。
创建用户
为数据库用户生成随机密码,并将其写入名为 dbpassword 的文件中:
cat /dev/urandom | LC_ALL=C tr -dc '[:alpha:]'| fold -w 50 | head -n1 > dbpassword
控制台
在 Google Cloud 控制台中,前往 Cloud SQL 实例页面。
选择 INSTANCE_NAME 实例。
转到用户标签页。
点击添加用户账号。
在内置身份验证对话框下:
- 输入用户名
DATABASE_USERNAME。 - 输入
dbpassword文件的内容作为密码PASSWORD。
- 输入用户名
点击添加。
gcloud
在最近创建的实例中创建用户,并将其密码设置为 dbpassword 的内容:
gcloud sql users create DATABASE_USERNAME \ --instance=INSTANCE_NAME --password=$(cat dbpassword)将
DATABASE_USERNAME替换为实例中用户的名称。
设置 Artifact Registry 制品库
使用 Artifact Registry 创建制品库以存储您的容器映像。
控制台
在 Google Cloud 控制台中,前往 Artifact Registry 页面。
点击创建代码库。
输入以下内容:
- 对于名称,请输入“cloud-run-source-deploy”。
- 在格式字段中,选择“Docker”。
- 对于区域,请选择 REGION。
对于其他字段,请保留默认值。
点击创建。
gcloud
创建 Artifact Registry 代码库:
gcloud artifacts repositories create cloud-run-source-deploy \ --repository-format docker \ --location REGION
设置 Cloud Storage 存储分区
您可以使用 Cloud Storage 在高度可用的对象存储中托管 Rails 静态资源和用户上传的媒体。
控制台
- 在 Google Cloud 控制台中,前往 Cloud Storage 存储分区页面。
- 点击 创建。
- 在创建存储桶页面上,输入您的存储桶信息。要转到下一步,请点击继续。
- 点击创建。
gcloud
创建 Cloud Storage 存储分区。 如需创建唯一的 Cloud Storage 存储桶名称,请使用 PROJECT_ID 和您选择的后缀
MEDIA_BUCKET_SUFFIX。在 Cloud Storage 中,存储桶名称必须是全局唯一的。gcloud storage buckets create gs://PROJECT_ID-MEDIA_BUCKET_SUFFIX \ --location=REGION
创建存储桶后,如需将上传的图片设为公开,请更改图片对象的权限,以供所有人读取。
控制台
- 在 Google Cloud 控制台中,转到 Cloud Storage 存储桶页面。
在存储桶列表中,点击您要设为公开的存储桶的名称。
选择页面顶部附近的权限标签。
点击添加成员按钮。
系统会显示添加成员对话框。
在新成员字段中,输入
allUsers。在选择角色下拉菜单中,选择 Cloud Storage 子菜单,然后点击 Storage Object Viewer 选项。
点击保存。
对象群组被公开共享后,“公共访问权限”列中会针对每个对象显示一个链接图标。您可以点击此图标来获取相应对象的网址。
如需了解如何在 Google Cloud 控制台中获取失败的 Ruby 操作的详细错误信息,请参阅问题排查。
gcloud
使用
gcloud storage buckets add-iam-policy-binding命令将所有对象设为公开。使用您在创建存储桶时使用的MEDIA_BUCKET_SUFFIX值。gcloud storage buckets add-iam-policy-binding gs://PROJECT_ID-MEDIA_BUCKET_SUFFIX \ --member=allUsers --role=roles/storage.objectViewer
在 Secret Manager 中存储 Secret 值
现在,支持性服务已配置完毕,Rails 需要安全信息(如密码)来访问这些服务。本教程使用 Rails 凭据和 Secret Manager 安全地存储这些值,而不是直接将这些信息放入 Rails 源代码中。
创建加密凭据文件并将密钥存储为 Secret Manager Secret
Rails 将 Secret 存储在名为“config/credentials.yml.enc”的加密文件中。您可以使用本地 config/master.key 或环境变量 ENV["RAILS_MASTER_KEY"] 对文件进行解密。在凭据文件中,您可以存储 Cloud SQL 实例数据库密码以及外部 API 的其他访问密钥。
您可以将此密钥安全地存储在 Secret Manager 中。然后,您可以向 Cloud Run 和 Cloud Build 授予密钥访问权限,方法是向各自的服务账号授予访问权限。服务账号通过包含项目编号的电子邮件地址进行标识。
使用以下命令生成
config/credentials.yml.enc文件:bin/rails credentials:edit如果未定义主密钥,则此命令将创建
config/master.key;如果config/credentials.yml.enc文件不存在,则此命令将创建该文件。这将在您的默认$EDITOR中打开一个临时文件,其中包含要添加的 Secret 的解密内容。将新创建的 PostgreSQL 实例数据库密码从
dbpassword文件复制并粘贴到凭据文件中:secret_key_base: GENERATED_VALUE gcp: db_password: PASSWORD可以使用
Rails.application.credentials访问 Secret。例如,Rails.application.credentials.secret_key_base应返回应用的 Secret 密钥库,而Rails.application.credentials.gcp[:db_password]应返回您的数据库密码。config/credentials/yml.enc以加密方式存储,但config/master.key可存储在 Secret Manager 中。控制台
在 Google Cloud 控制台中,前往 Secret Manager 页面。
点击创建 Secret。
在名称字段中,输入 secret
RAILS_SECRET_NAME的名称。在 Secret 值对话框中,将 mater.key 值粘贴到框中。
点击创建密钥。
在 Secret 的“Secret 详情”页面上,记下项目编号:
projects/PROJECTNUM/secrets/RAILS_SECRET_NAME
在权限标签页中,点击添加成员。
在新成员字段中,输入
PROJECTNUM-compute@developer.gserviceaccount.com,然后按Enter。在新成员字段中,输入
PROJECTNUM@cloudbuild.gserviceaccount.com,然后按Enter。在角色下拉菜单中,选择 Secret Manager Secret Accessor。
点击保存。
gcloud
使用 config/master.key 的值创建新 Secret:
gcloud secrets create RAILS_SECRET_NAME --data-file config/master.key将
RAILS_SECRET_NAME替换为新 Secret 的名称。要确认创建 Secret,请进行检查:
gcloud secrets describe RAILS_SECRET_NAME gcloud secrets versions access latest --secret RAILS_SECRET_NAME获取项目编号的值:
gcloud projects describe PROJECT_ID --format='value(projectNumber)'向 Cloud Run 服务账号授予对 Secret 的访问权限:
gcloud secrets add-iam-policy-binding RAILS_SECRET_NAME \ --member serviceAccount:PROJECTNUM-compute@developer.gserviceaccount.com \ --role roles/secretmanager.secretAccessor将
PROJECTNUM替换为项目编号值。向 Cloud Build 服务账号授予对 Secret 的访问权限:
gcloud secrets add-iam-policy-binding RAILS_SECRET_NAME \ --member serviceAccount:PROJECTNUM@cloudbuild.gserviceaccount.com \ --role roles/secretmanager.secretAccessor在输出中,确认
bindings将两个服务账号列为成员。
将 Rails 应用连接到生产数据库和存储空间
本教程使用 PostgreSQL 实例作为生产数据库,使用 Cloud Storage 作为存储后端。为了让 Rails 连接到新创建的数据库和存储桶,您需要在 .env 文件中指定访问它们所需的全部信息。.env 文件包含应用环境变量的配置。应用将使用 dotenv gem 读取此文件。由于 Secret 存储在 credentials.yml.enc 和 Secret Manager 中,因此 .env 不必加密,因为它不含任何敏感凭据。
- 打开
.env文件,以将 Rails 应用配置为与数据库和存储桶连接。 将
.env文件配置修改为以下内容。使用您在创建存储桶时使用的MEDIA_BUCKET_SUFFIX值。PRODUCTION_DB_NAME: DATABASE_NAME PRODUCTION_DB_USERNAME: DATABASE_USERNAME CLOUD_SQL_CONNECTION_NAME: PROJECT_ID:REGION:INSTANCE_NAME GOOGLE_PROJECT_ID: PROJECT_ID STORAGE_BUCKET_NAME: PROJECT_ID-MEDIA_BUCKET_SUFFIXRails 应用现已设置为在部署到 Cloud Run 时使用 Cloud SQL 和 Cloud Storage。
将应用部署到 Cloud Run
设置支持性服务后,您现在可以将应用部署为 Cloud Run 服务。
借助提供的
cloudbuild.yaml,使用 Cloud Build 构建映像、运行数据库迁移并填充静态资源:gcloud builds submit --config cloudbuild.yaml \ --substitutions _SERVICE_NAME=SERVICE_NAME,_INSTANCE_NAME=INSTANCE_NAME,_REGION=REGION,_SECRET_NAME=RAILS_SECRET_NAME将
SERVICE_NAME替换为您的服务的名称。第一次构建需要几分钟才能完成。 如果构建超时,请在构建命令中插入 --timeout=2000s,以增加超时时长。构建成功后,首次部署 Cloud Run 服务,设置服务区域、基础映像和连接的 Cloud SQL 实例:
gcloud run deploy SERVICE_NAME \ --region REGION \ --image REGION-docker.pkg.dev/PROJECT_ID/cloud-run-source-deploy/SERVICE_NAME \ --add-cloudsql-instances PROJECT_ID:REGION:INSTANCE_NAME \ --allow-unauthenticated您应该会看到输出,显示部署成功,并提供一个服务网址。
如需查看已部署的服务,请转到该服务网址。
如果服务网址显示猫相册,则表示您位于应用的首页上。 尝试上传一张新照片。如果照片成功上传,则表示 Rails 应用已成功部署。
如果服务网址显示猫相册,则表示您位于应用的首页上。
更新应用
虽然初始预配和部署步骤很复杂,但更新过程比较简单:
运行 Cloud Build 构建和迁移脚本:
gcloud builds submit --config cloudbuild.yaml \ --substitutions _SERVICE_NAME=SERVICE_NAME,_INSTANCE_NAME=INSTANCE_NAME,_REGION=REGION,_SECRET_NAME=RAILS_SECRET_NAME部署服务,仅指定区域和映像:
gcloud run deploy SERVICE_NAME \ --region REGION \ --image REGION-docker.pkg.dev/PROJECT_ID/cloud-run-source-deploy/SERVICE_NAME
了解代码
Rails 示例应用是使用标准 Rails 命令创建的。以下命令会创建 cat_album 应用并使用 scaffold 命令生成照片资源的模型、控制器和视图:
rails new cat_album
rails generate scaffold Photo caption:text
数据库连接
config/database.yml 文件包含访问不同环境(开发、测试、生产)中的数据库所需的配置。例如,生产数据库配置为在 Cloud SQL for PostgreSQL 中运行。数据库名称和用户名通过 .env 文件中的环境变量设置,而数据库密码存储在 config/credentials.yml.enc 文件中,该文件需要使用 RAILS_MASTER_KEY 进行解密。
当应用在 Cloud Run(全代管式)上运行时,它会使用 Cloud Run 环境提供的套接字连接到 PostgreSQL 实例。当应用在本地机器上运行时,它会使用 Cloud SQL Auth 代理连接到 PostgreSQL 实例。
云存储的用户上传媒体
Rails 使用 Active Storage 将文件上传到存储服务提供商。config/storage.yml 和 config/environments/production.rb 文件将 Cloud Storage 指定为生产环境中的服务提供商。
使用 Cloud Build 实现自动化
cloudbuild.yaml 文件不仅可以执行典型的映像构建步骤(创建容器映像并将其推送到 Artifact Registry),还可以执行 Rails 数据库迁移。此迁移使用 Cloud Run 作业执行,其中使用自定义命令,以便容器执行迁移,而不是默认的 Web 服务器。
此配置中使用替代变量。直接更改文件中的值意味着您可以在迁移时舍弃 --substitutions 标志。
在此配置中,仅应用 db/migrate 目录中的现有迁移。如需创建迁移文件,请参阅 Active Record Migrations。
如需构建映像并应用迁移,Cloud Build 配置需要有权从 Secret Manager 访问 RAILS_MASTER_KEY Secret。availableSecrets 字段设置用于 Secret 的 Secret 版本和环境变量。主密钥 Secret 会在构建映像步骤中作为参数传入,然后构建映像时在 Dockerfile 中设置为 RAILS_MASTER_KEY。
如需扩展 Cloud Build 配置以将该部署包含在一个配置中,而无需运行两个命令,请参阅使用 Cloud Build 通过 Git 实现持续部署。正如 IAM 所述,这需要更改 IAM。
清理
- 在 Google Cloud 控制台中,前往管理资源页面。
- 在项目列表中,选择要删除的项目,然后点击删除。
- 在对话框中输入项目 ID,然后点击关闭以删除项目。