サンプル 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を初めて使用する場合は、 アカウントを作成して、実際のシナリオでの Google プロダクトのパフォーマンスを評価してください。新規のお客様には、ワークロードの実行、テスト、デプロイができる無料クレジット $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 をインストールします。
-
外部 ID プロバイダ(IdP)を使用している場合は、まず連携 ID を使用して 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 をインストールします。
-
外部 ID プロバイダ(IdP)を使用している場合は、まず連携 ID を使用して gcloud CLI にログインする必要があります。
-
gcloud CLI を初期化するには、次のコマンドを実行します。
gcloud init - このチュートリアルで使用するアカウントに十分な権限が付与されていることを確認してください。
環境を準備する
このチュートリアルでは、さまざまな Google Cloud サービスを使用して、デプロイ済みの Rails アプリケーションをサポートするデータベース、メディア ストレージ、シークレット ストレージを準備します。サービスをデプロイするリージョンを構成し、Rails アプリを複製して、環境を準備します。
デフォルトのプロジェクトとリージョンを設定する
gcloud CLI のデフォルトのプロジェクト構成は、次のコマンドを実行して設定します。
gcloud config set project PROJECT_IDPROJECT_IDは、 Google Cloudプロジェクト ID に置き換えます。リージョンを構成します。
export REGION=REGIONREGIONは、適切なロケーションに置き換えます。サービス間の効率を高めるために、すべてのサービスを同じリージョンにデプロイすることをおすすめします。最も近いリージョンの詳細については、ロケーション別のプロダクト提供状況をご覧ください。
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 プロジェクトをサポートするデータベース、メディア ストレージ、シークレット ストレージを準備します。これらのサービスは、特定のリージョンにデプロイされます。サービス間の効率を高めるために、すべてのサービスを同じリージョンにデプロイすることをおすすめします。最も近いリージョンの詳細については、ロケーション別のプロダクト提供状況をご覧ください。
Cloud SQL for PostgreSQL インスタンスを設定する
Rails は、Cloud SQL で提供されているものを含め、複数のリレーショナル データベースに対応しています。このチュートリアルでは、Rails アプリでよく使用されるオープンソース データベースである PostgreSQL を使用します。
以降のセクションでは、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_NAMEDATABASE_NAMEを、このインスタンス内のデータベースの名前に置き換えます。
ユーザーを作成する
データベース ユーザーのランダムなパスワードを生成し、dbpassword という名前のファイルに書き込みます。
cat /dev/urandom | LC_ALL=C tr -dc '[:alpha:]'| fold -w 50 | head -n1 > dbpassword
Console
Google Cloud コンソールで、Cloud SQL の [インスタンス] ページに移動します。
INSTANCE_NAME インスタンスを選択します。
[ユーザー] タブに移動します。
[ユーザー アカウントを追加] をクリックします。
[組み込み認証] ダイアログで、次の操作を行います。
DATABASE_USERNAMEというユーザー名を入力します。dbpasswordファイルの内容をパスワードPASSWORDとして入力します。
[Add] をクリックします。
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 バケットを設定する
Rails の静的アセットとユーザーがアップロードしたメディアを、Cloud Storage を使用する高可用性オブジェクト ストレージでホストできます。
コンソール
- Google Cloud コンソールで、Cloud Storage の [バケット] ページに移動します。
- [ 作成] をクリックします。
- [バケットの作成] ページでユーザーのバケット情報を入力します。次のステップに進むには、[続行] をクリックします。
- [始める] セクションで、次の操作を行います。
- [ロケーション] で、次の項目を選択します。 us-central1
-
[データの保存場所を選択する] セクションで、次の操作を行います。
- [デフォルトのクラスを設定する] セクションで、[標準] を選択します。
- 階層名前空間を有効にするには、[データ量が多いワークロード向けにストレージを最適化] セクションで、[このバケットで階層的な名前空間を有効にする] を選択します。
- [オブジェクトへのアクセスを制御する方法を選択する] セクションで、バケットに公開アクセスの防止を適用するかどうかを選択し、バケットのオブジェクトに使用するアクセス制御方法を選択します。
-
[オブジェクト データを保護する方法を選択する] セクションで、次の操作を行います。
- [データ保護] で、バケットに設定するオプションを選択します。
- 削除(復元可能)を有効にするには、[削除(復元可能)ポリシー(データ復元用)] チェックボックスをオンにして、削除後にオブジェクトを保持する日数を指定します。
- オブジェクトのバージョニングを設定するには、[オブジェクトのバージョニング(バージョン管理用)] チェックボックスをオンにして、オブジェクトあたりの最大バージョン数と、非現行バージョンの有効期限が切れるまでの日数を指定します。
- オブジェクトとバケットで保持ポリシーを有効にするには、[保持(コンプライアンス用)] チェックボックスをオンにして、次の操作を行います。
- オブジェクト保持ロックを有効にするには、[オブジェクト保持を有効にする] チェックボックスをオンにします。
- バケットロックを有効にするには、[バケット保持ポリシーを設定] チェックボックスをオンにして、保持期間の単位と期間を選択します。
- オブジェクト データの暗号化方法を選択するには、[データ暗号化] セクション()を開き、データ暗号化方法を選択します。
- [データ保護] で、バケットに設定するオプションを選択します。
- [作成] をクリックします。
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] サブメニューを選択し、[ストレージ オブジェクト閲覧者] オプションをクリックします。
[保存] をクリックします。
公開の状態で共有されると、[公開アクセス] 列に各オブジェクトのリンクアイコンが表示されます。このアイコンをクリックすると、オブジェクトの URL を取得できます。
失敗した Ruby オペレーションの詳細なエラー情報を Google Cloud コンソールで確認する方法については、トラブルシューティングをご覧ください。
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 にシークレット値を保存する
バッキング サービスの構成が完了したので、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に一時ファイルが開き、シークレット用に復号されたコンテンツが追加されます。新しく作成した PostgreSQL インスタンス データベース パスワードを
dbpasswordファイルからコピーして、認証情報ファイルに貼り付けます。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] ページに移動します。
[シークレットの作成] をクリックします。
[名前] フィールドに、シークレットの名前
RAILS_SECRET_NAMEを入力します。[シークレットの値] ダイアログで、mater.key の値をボックスに貼り付けます。
[シークレットの作成] をクリックします。
シークレットの [シークレットの詳細] ページで、プロジェクト番号をメモします。
projects/PROJECTNUM/secrets/RAILS_SECRET_NAME
[権限] タブで、[メンバーを追加] をクリックします。
[新しいメンバー] フィールドに「
PROJECTNUM-compute@developer.gserviceaccount.com」と入力し、Enterを押します。[新しいメンバー] フィールドに「
PROJECTNUM@cloudbuild.gserviceaccount.com」と入力し、Enterを押します。[ロール] プルダウン メニューで [Secret Manager のシークレット アクセサー] を選択します。
[保存] をクリックします。
gcloud
config/master.key の値を含む新しいシークレットを作成します。
gcloud secrets create RAILS_SECRET_NAME --data-file config/master.keyRAILS_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)'Cloud Run サービス アカウントにシークレットへのアクセス権を付与します。
gcloud secrets add-iam-policy-binding RAILS_SECRET_NAME \ --member serviceAccount:PROJECTNUM-compute@developer.gserviceaccount.com \ --role roles/secretmanager.secretAccessorPROJECTNUMは、プロジェクト番号の値に置き換えます。Cloud Build サービス アカウントにシークレットへのアクセス権を付与します。
gcloud secrets add-iam-policy-binding RAILS_SECRET_NAME \ --member serviceAccount:PROJECTNUM@cloudbuild.gserviceaccount.com \ --role roles/secretmanager.secretAccessor出力で、
bindingsが 2 つのサービス アカウントをメンバーとしてリストしていることを確認します。
Rails アプリを本番環境のデータベースとストレージに接続する
このチュートリアルでは、本番環境データベースとして PostgreSQL インスタンスを使用し、ストレージ バックエンドとして Cloud Storage を使用します。新しく作成したデータベースとストレージ バケットに Rails を接続するには、アクセスするために必要なすべての情報を .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_SUFFIXこれで、Cloud Run へのデプロイ時に Cloud SQL と Cloud Storage を使用するように Rails アプリが設定されました。
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_NAMESERVICE_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サービスの URL とともに、デプロイが成功したことを示す出力が表示されます。
デプロイされたサービスを確認するには、サービスの URL に移動します。
サービス URL に猫のフォトアルバムが表示されている場合は、アプリのホームページが表示されています。 新しい写真をアップロードしてみてください。写真が正常にアップロードされると、Rails アプリケーションが正常にデプロイされています。
サービス URL に猫のフォトアルバムが表示されている場合は、アプリのホームページが表示されています。
アプリケーションを更新する
最初のプロビジョニングとデプロイの手順は複雑でしたが、更新はより簡単なプロセスです。
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 ファイルには、さまざまな環境(開発環境、テスト環境、本番環境)でデータベースにアクセスするために必要な構成が含まれています。たとえば、本番環境のデータベースは、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 に push する)だけでなく、Rails データベースの移行も行います。この移行は Cloud Run ジョブを使用して実行されます。ここでは、デフォルトのウェブサーバーではなく、コンテナが移行を実行するようにカスタム コマンドが使用されます。
この構成では代入変数が使用されます。ファイルの値を直接変更すると、移行時に --substitutions フラグを省略できます。
この構成では、db/migrate ディレクトリ内の既存の移行のみが適用されます。移行ファイルを作成するには、Active Record Migrations をご覧ください。
イメージをビルドして移行を適用するには、Cloud Build 構成が Secret Manager の RAILS_MASTER_KEY シークレットにアクセスする必要があります。availableSecrets フィールドには、シークレットに使用するシークレットのバージョンと環境変数を設定します。マスター鍵のシークレットは、ビルドイメージの手順で引数として渡され、イメージのビルド時に Dockerfile 内で RAILS_MASTER_KEY に設定されます。
2 つのコマンドを実行せずに 1 つの構成にデプロイを含めるように Cloud Build の構成を拡張するには、Cloud Build を使用した git による継続的デプロイをご覧ください。説明されているように、これには IAM の変更が必要です。
クリーンアップ
- Google Cloud コンソールで [リソースの管理] ページに移動します。
- プロジェクト リストで、削除するプロジェクトを選択し、[削除] をクリックします。
- ダイアログでプロジェクト ID を入力し、[シャットダウン] をクリックしてプロジェクトを削除します。