サンプル Rails アプリケーションを Cloud Run にデプロイする方法、およびマネージド データベース、オブジェクト ストレージ、暗号化されたシークレット、ビルド パイプラインをサーバーレス コンピューティングと統合する方法を学びます。
Rails アプリケーションをデプロイするには、複数のサービスを組み合わせて統合プロジェクトを作成します。このチュートリアルは、Rails ウェブ開発の知識があることを前提としています。
このチュートリアルでは、Ruby 3.0 以降(Ruby 2.7 もサポートされています。「コードを理解する」セクションをご覧ください)と Rails 6 以降が必要です。
目標
- Cloud SQL データベースを作成して Active Record に接続する
- Secret Manager を作成して使用し、Rails マスター鍵に安全に保存してアクセスする
- Active Storage から Cloud Storage にユーザーがアップロードしたメディアとファイルをホストする
- Cloud Build を使用してビルドとデータベースの移行を自動化する
- Rails アプリを Cloud Run にデプロイする
費用
始める前に
- Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Make sure that billing is enabled for your Google Cloud project.
-
Enable the Cloud Run, Cloud SQL, Cloud Build, Secret Manager, and Compute Engine APIs.
- Install the Google Cloud CLI.
-
To initialize the gcloud CLI, run the following command:
gcloud init
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Make sure that billing is enabled for your Google Cloud project.
-
Enable the Cloud Run, Cloud SQL, Cloud Build, Secret Manager, and Compute Engine APIs.
- Install the Google Cloud CLI.
-
To initialize the gcloud CLI, run the following command:
gcloud init
- このチュートリアルで使用するアカウントに十分な権限が付与されていることを確認してください。
環境の準備
デフォルト プロジェクトの設定
gcloud CLI のデフォルトのプロジェクト構成は、次のコマンドを実行して設定します。
gcloud config set project PROJECT_ID
PROJECT_ID
を新しく作成した Google Cloud プロジェクト ID に置き換えます。
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 install
Windows
cd ruby-docs-samples\run\rails bundle install
バッキング サービスの準備
このチュートリアルでは、さまざまな Google Cloud サービスを使用して、デプロイ済みの Rails プロジェクトをサポートするデータベース、メディア ストレージ、シークレット ストレージを準備します。これらのサービスは、特定のリージョンにデプロイされます。サービス間の効率を高めるために、すべてのサービスを同じリージョンにデプロイすることをおすすめします。最も近いリージョンの詳細については、リージョン別に提供されるプロダクトをご覧ください。
Cloud SQL for PostgreSQL インスタンスを設定する
Rails は、Cloud SQL で提供されているものを含め、複数のリレーショナル データベースに対応しています。このチュートリアルでは、Rails アプリでよく使用されるオープンソース データベースである PostgreSQL を使用します。
以降のセクションでは、Rails アプリ用に PostgreSQL インスタンス、データベース、データベース ユーザーを作成する方法について説明します。
PostgreSQL インスタンスを作成する
Console
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 リージョン
インスタンスの作成と使用準備が完了するまでに数分かかります。
データベースの作成
Console
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
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
を、このインスタンス内のユーザーの名前に置き換えます。
Cloud Storage バケットを設定する
Rails の静的アセットとユーザーがアップロードしたメディアを、Cloud Storage を使用する高可用性オブジェクト ストレージでホストできます。
Console
- In the Google Cloud console, go to the Cloud Storage Buckets page.
- Click Create bucket.
- On the Create a bucket page, enter your bucket information. To go to the next
step, click Continue.
- For Name your bucket, enter a name that meets the bucket naming requirements.
- For Location, select the following: us-central1
- For Choose a default storage class for your data, select the following: Standard.
- For Choose how to control access to objects, select an Access control option.
- For Advanced settings (optional), specify an encryption method, a retention policy, or bucket labels.
- Click Create.
gcloud
gsutil
コマンドライン ツールは、gcloud CLI のインストールの一部としてインストールされます。
Cloud Storage バケットを作成します。一意の Cloud Storage バケット名を作成するには、PROJECT_ID と任意の接尾辞(
MEDIA_BUCKET_SUFFIX
)を使用します。Cloud Storage では、バケット名は、グローバルに一意でなければなりません。gsutil mb -l REGION gs://PROJECT_ID-MEDIA_BUCKET_SUFFIX
バケットの作成後、アップロードした画像を公開するには、誰でも閲覧できるように画像オブジェクトの権限を変更します。
Console
- Google Cloud コンソールで、Cloud Storage の [バケット] ページに移動します。
バケットのリストで、公開するバケットの名前をクリックします。
ページ上部にある [権限] タブを選択します。
[メンバーを追加] ボタンをクリックします。
[メンバーを追加] ダイアログ ボックスが表示されます。
[新しいメンバー] フィールドに「
allUsers
」と入力します。[役割を選択] プルダウンで [Cloud Storage] サブメニューを選択し、[ストレージ オブジェクト閲覧者] オプションをクリックします。
[保存] をクリックします。
公開の状態で共有されると、[公開アクセス] 列に各オブジェクトのリンクアイコンが表示されます。このアイコンをクリックすると、オブジェクトの URL を取得できます。
Google Cloud コンソールで失敗した Ruby オペレーションに関する詳細なエラー情報を確認する方法については、トラブルシューティングをご覧ください。
gcloud
すべてのオブジェクトを公開するには、
gsutil iam ch
コマンドを使用します。バケットの作成時に使用したMEDIA_BUCKET_SUFFIX
の値を使用します。gsutil iam ch allUsers:objectViewer gs://PROJECT_ID-MEDIA_BUCKET_SUFFIX
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_passsword]
はデータベース パスワードを返します。config/credentials/yml.enc
は暗号化されて保存されますが、config/master.key
は Secret Manager に保存することができます。Console
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.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)'
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
が 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 Build に Cloud SQL へのアクセス権を付与する
Cloud Build でデータベースの移行を適用するには、Cloud Build に Cloud SQL へのアクセス権を付与する必要があります。
Console
Google Cloud コンソールで、[Identity and Access Management] ページに移動します。
PROJECTNUM@cloudbuild.gserviceaccount.com
メンバーのエントリを編集するには、 [メンバーを編集] をクリックします。[別のロールを追加] をクリックします。
[ロールを選択] ダイアログで、[Cloud SQL クライアント] を選択します。
[保存] をクリックします。
gcloud
Cloud Build に Cloud SQL へのアクセス権を付与します。
gcloud projects add-iam-policy-binding PROJECT_ID \ --member serviceAccount:PROJECTNUM@cloudbuild.gserviceaccount.com \ --role roles/cloudsql.client
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 \ --platform managed \ --region REGION \ --image gcr.io/PROJECT_ID/SERVICE_NAME \ --add-cloudsql-instances PROJECT_ID:REGION:INSTANCE_NAME \ --allow-unauthenticated
サービスの URL とともに、デプロイが成功したことを示す出力が表示されます。
Service [SERVICE_NAME] revision [SERVICE_NAME-00001-tug] has been deployed and is serving 100 percent of traffic at https://SERVICE_NAME-
HASH
-uc.a.run.appデプロイされたサービスを確認するには、サービスの URL に移動します。
新しい写真をアップロードしてみてください。写真が正常にアップロードされると、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 \ --platform managed \ --region REGION \ --image gcr.io/PROJECT_ID/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 ファイルは、一般的なイメージ ビルドステップ(コンテナ イメージを作成して Container Registry に push する)だけでなく、Rails データベースの移行も行います。これにはデータベースへのアクセスが必要です。これは、app-engine-exec-wrapper(Cloud SQL Auth プロキシのヘルパー)を使用して実行されます。
この構成では代入変数が使用されます。ファイルの値を直接変更すると、移行時に --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 の変更が必要です。
Ruby 2.7 のサポート
このチュートリアルでは Ruby 3.0 を使用していますが、Ruby 2.7 もサポートできます。Ruby 2.7 を使用するには、Dockerfile 内の Ruby ベースイメージを 2.7 に変更します。
クリーンアップ
- In the Google Cloud console, go to the Manage resources page.
- In the project list, select the project that you want to delete, and then click Delete.
- In the dialog, type the project ID, and then click Shut down to delete the project.