瞭解如何將 Rails 範例應用程式部署至 Cloud Run,以及如何整合代管資料庫、物件儲存空間、加密密鑰和建構管道與無伺服器運算。
部署 Rails 應用程式時,需要整合多項服務,才能形成連貫的專案。本教學課程假設您已熟悉 Rails 網路開發流程。
本教學課程需要 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 應用程式的資料庫、媒體儲存空間和密鑰儲存空間。設定要部署服務的區域,並複製 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 專案的資料庫、媒體儲存空間和密鑰儲存空間。這些服務部署在特定區域。為提高服務間的效率,建議您在同一個區域部署所有服務。如要進一步瞭解離您最近的區域,請參閱「各個地區適用的產品」。
設定 PostgreSQL 適用的 Cloud SQL 執行個體
Rails 支援多個關聯式資料庫,包括 Cloud SQL 提供的多個資料庫。本教學課程使用 PostgreSQL,這是 Rails 應用程式常用的開放原始碼資料庫。
以下各節說明如何為 Rails 應用程式建立 PostgreSQL 執行個體、資料庫和資料庫使用者。
建立 PostgreSQL 執行個體。
控制台
前往 Google Cloud 控制台的「Cloud SQL Instances」頁面。
點選「建立執行個體」。
按一下「Choose PostgreSQL」(選擇 PostgreSQL)。
在「Instance ID」(執行個體 ID) 欄位中,輸入執行個體的名稱 (
INSTANCE_NAME)。在「Password」(密碼) 欄位中,輸入 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 Instances」頁面。
選取 INSTANCE_NAME 執行個體。
前往「資料庫」分頁。
按一下 [Create database] (建立資料庫)。
在「Database 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 Instances」頁面。
選取 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」頁面。
點選「Create Repository」。
輸入下列指令:
- 針對「Name」(名稱) 輸入「cloud-run-source-deploy」。
- 在「格式」中,選取「Docker」。
- 在「Region」(區域) 中選取 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「Buckets」(值區) 頁面。
- 點選 「Create」(建立)。
- 在「建立 bucket」頁面中,輸入 bucket 資訊。如要前往下一個步驟,請按「繼續」。
- 在「開始使用」部分,執行下列操作:
- 在「位置」中,選取下列項目: us-central1
-
在「選擇資料儲存方式」部分,執行下列操作:
- 在「設定預設類別」部分,選取「Standard」。
- 如要啟用階層命名空間,請在「為資料密集型工作負載提供最理想的儲存空間」部分,選取「為這個值區啟用階層命名空間」。
- 在「選取如何控制物件的存取權」部分,選取 bucket 是否要強制執行禁止公開存取,並為 bucket 的物件選取存取權控管方法。
-
在「選擇保護物件資料的方式」部分,執行下列操作:
- 在「資料保護」下方,選取要為 bucket 設定的選項。
- 如要啟用虛刪除,請按一下「虛刪除政策 (用於資料復原)」核取方塊,並指定要保留物件的天數 (刪除後)。
- 如要設定「物件版本管理」,請按一下「物件版本管理 (用於版本管控)」核取方塊,並指定每個物件的版本數量上限,以及非現行版本失效的天數。
- 如要為物件和 bucket 啟用保留政策,請勾選「保留 (符合法規)」核取方塊,然後執行下列操作:
- 如要啟用 Object Retention Lock,請按一下「啟用物件保留功能」核取方塊。
- 如要啟用「Bucket Lock」,請勾選「Set bucket retention policy」(設定值區保留政策) 核取方塊,然後選擇保留期限的時間單位和長度。
- 如要選擇物件資料的加密方式,請展開「資料加密」部分 (),然後選取「資料加密」方法。
- 在「資料保護」下方,選取要為 bucket 設定的選項。
- 點選「建立」。
gcloud
建立 Cloud Storage bucket。如要建立不重複的 Cloud Storage bucket 名稱,請使用 PROJECT_ID 和您選擇的後置字串
MEDIA_BUCKET_SUFFIX。在 Cloud Storage 中,bucket 名稱不得重複。gcloud storage buckets create gs://PROJECT_ID-MEDIA_BUCKET_SUFFIX \ --location=REGION
建立值區後,如要將上傳的圖片設為公開,請將圖片物件的權限變更為所有人皆可讀取。
控制台
- 前往 Google Cloud 控制台的「Cloud Storage bucket」頁面。
在 bucket 清單中,找到要設為公開的 bucket 名稱,然後點選這個名稱。
選取靠近頁面上方的 [Permissions] (權限) 分頁標籤。
按一下 [Add members] (新增成員) 按鈕。
系統會顯示「新增成員」對話方塊。
在「New members」(新增成員) 欄位中,輸入
allUsers。在「請選擇角色」下拉式選單中,選取「Cloud Storage」子選單,然後點選「Storage 物件檢視者」選項。
按一下 [儲存]。
公開共用後,「public access」(公開存取權) 欄中會出現各個物件的連結圖示。您可以按一下這個圖示來取得物件的網址。
如要瞭解如何在 Google Cloud 控制台中取得 Ruby 作業失敗的詳細錯誤資訊,請參閱「疑難排解」。
gcloud
使用
gcloud storage buckets add-iam-policy-binding指令將所有物件設為公開。請使用建立 bucket 時使用的MEDIA_BUCKET_SUFFIX值。gcloud storage buckets add-iam-policy-binding gs://PROJECT_ID-MEDIA_BUCKET_SUFFIX \ --member=allUsers --role=roles/storage.objectViewer
將密鑰值儲存在 Secret Manager
後端服務設定完成後,Rails 需要密碼等安全資訊,才能存取這些服務。本教學課程不會直接將這些值放入 Rails 原始碼,而是使用 Rails 憑證和 Secret Manager 安全地儲存這項資訊。
建立加密憑證檔案,並將金鑰儲存為 Secret Manager 密鑰
Rails 會將密碼儲存在名為「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中開啟臨時檔案,其中包含要新增密鑰的解密內容。從
dbpassword檔案複製並貼上新建立的 PostgreSQL 執行個體資料庫密碼到憑證檔案:secret_key_base: GENERATED_VALUE gcp: db_password: PASSWORD您可以使用
Rails.application.credentials存取密鑰。舉例來說,Rails.application.credentials.secret_key_base應傳回應用程式的密鑰基礎,而Rails.application.credentials.gcp[:db_password]應傳回資料庫密碼。config/credentials/yml.enc會經過加密儲存,但config/master.key可以儲存在 Secret Manager 中。控制台
前往 Google Cloud 控制台的「Secret Manager」頁面。
按一下「建立密鑰」。
在「Name」(名稱) 欄位中,輸入密鑰名稱
RAILS_SECRET_NAME。在「Secret value」(密鑰值) 對話方塊中,將 master.key 值貼到方塊中。
按一下「建立密鑰」。
在密鑰的「Secret details」(密鑰詳細資料) 頁面中,記下專案編號:
projects/PROJECTNUM/secrets/RAILS_SECRET_NAME
在「權限」分頁中,按一下「新增成員」
在「New Members」(新增成員) 欄位中輸入
PROJECTNUM-compute@developer.gserviceaccount.com,然後按Enter。在「New Members」(新增成員) 欄位中輸入
PROJECTNUM@cloudbuild.gserviceaccount.com,然後按Enter。在「角色」下拉式選單中,選取「Secret Manager 密鑰存取者」。
按一下 [儲存]。
gcloud
使用 config/master.key 的值建立新密鑰:
gcloud secrets create RAILS_SECRET_NAME --data-file config/master.key將
RAILS_SECRET_NAME替換為新密鑰的名稱。如要確認密鑰是否建立完成,請檢查:
gcloud secrets describe RAILS_SECRET_NAME gcloud secrets versions access latest --secret RAILS_SECRET_NAME取得專案編號的值:
gcloud projects describe PROJECT_ID --format='value(projectNumber)'將 Secret 的存取權授予 Cloud Run 服務帳戶:
gcloud secrets add-iam-policy-binding RAILS_SECRET_NAME \ --member serviceAccount:PROJECTNUM-compute@developer.gserviceaccount.com \ --role roles/secretmanager.secretAccessor將
PROJECTNUM替換為專案編號值。將密鑰的存取權授予 Cloud Build 服務帳戶:
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 連線至新建立的資料庫和儲存空間 bucket,您需要在 .env 檔案中指定存取這些資源所需的所有資訊。.env 檔案包含應用程式環境變數的設定。應用程式會使用 dotenv Gem 讀取這個檔案。由於密鑰儲存在 credentials.yml.enc 和 Secret Manager 中,因此 .env 不必加密,因為其中不含任何機密憑證。
- 如要設定 Rails 應用程式以連線至資料庫和儲存空間值區,請開啟
.env檔案。 將
.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輸出內容應會顯示部署作業成功,並附上服務網址。
如要查看已部署的服務,請前往服務網址。
如果服務網址顯示「Cat Photo Album」(貓咪相簿),表示您位於應用程式首頁。 請嘗試上傳新相片。如果相片上傳成功,表示 Rails 應用程式已順利部署。
如果服務網址顯示「Cat Photo Album」(貓咪相簿),表示您位於應用程式首頁。
更新應用程式
雖然初始佈建和部署步驟很複雜,但更新程序較為簡單:
執行 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 指令為 Photo 資源產生模型、控制器和檢視畫面:
rails new cat_album
rails generate scaffold Photo caption:text
資料庫連線
config/database.yml 檔案包含在不同環境 (開發、測試、實際工作) 中存取資料庫所需的設定。舉例來說,生產環境資料庫已設定為在 PostgreSQL 適用的 Cloud SQL 中執行。資料庫名稱和使用者名稱是在 .env 檔案中透過環境變數設定,而資料庫密碼則儲存在 config/credentials.yml.enc 檔案中,需要 RAILS_MASTER_KEY 才能解密。
應用程式在 Cloud Run (全代管) 上執行時,會使用 Cloud Run 環境提供的通訊端連線至 PostgreSQL 執行個體。應用程式在本機執行時,會使用 Cloud SQL 驗證 Proxy 連線至 PostgreSQL 執行個體。
雲端儲存的使用者上傳媒體
Rails 使用 Active Storage 將檔案上傳至儲存空間供應商。config/storage.yml 和 config/environments/production.rb 檔案會在正式環境中,將 Cloud Storage 指定為服務供應商。
使用 Cloud Build 自動化
cloudbuild.yaml 檔案不僅會執行一般的映像檔建構步驟 (建立容器映像檔並推送至 Artifact Registry),也會執行 Rails 資料庫遷移作業。這項遷移作業是透過 Cloud Run 工作執行,使用自訂指令,讓容器執行遷移作業,而非預設的網路伺服器。
這項設定會使用替代變數。直接變更檔案中的值,表示可以在遷移時捨棄 --substitutions 旗標。
在此設定中,系統只會套用 db/migrate 目錄中的現有遷移作業。如要建立遷移檔案,請參閱「Active Record Migrations」。
如要建構映像檔及套用遷移作業,Cloud Build 設定需要存取 Secret Manager 中的 RAILS_MASTER_KEY 密碼。availableSecrets 欄位會設定要用於 Secret 的 Secret 版本和環境變數。主金鑰 Secret 會以引數形式傳遞至建構映像檔步驟,然後在建構映像檔時,設定為 Dockerfile 中的 RAILS_MASTER_KEY。
如要擴充 Cloud Build 建構設定,在一個設定中納入部署作業,不必執行兩項指令,請參閱「透過 Cloud Build 從 Git 持續部署」。如上所述,這需要變更 IAM。
清除所用資源
- 前往 Google Cloud 控制台的「Manage resources」(管理資源) 頁面。
- 在專案清單中選取要刪除的專案,然後點選「Delete」(刪除)。
- 在對話方塊中輸入專案 ID,然後按一下 [Shut down] (關閉) 以刪除專案。