LoginSignup
8
0

More than 1 year has passed since last update.

【実践版】Rails アプリを Cloud Run で動かしてみよう

Posted at

【超シンプル版】Rails アプリを Cloud Run で動かしてみようで Cloud Run を使って Rails アプリを動かしてみました。
今回はもう少し実践で使えるようにデータベース、環境変数の設定、ログの収集、ビルドの自動化を構築していきたいと思います。

前提

以下の構成で作っていきます!
Untitled-2022-11-29-2139.png

追加で利用するプロダクト

  • Cloud SQL
  • Cloud Logging
  • Secret Manager

構築の流れ

  1. Rails アプリ作成
  2. Cloud SQL と接続する
  3. Secret Manager を利用する
  4. Cloud Logging を利用する
  5. 手動でビルド & デプロイ
  6. Cloud Build と GitHub を連携する

Rails アプリ作成

ここは前回とほぼ同じなので、説明は割愛します。

# Rails アプリ作成. データベースは MySQL にする
$ rails new sample-app -d mysql
$ cd sample-app

# scaffold でページ作成
$ bin/rails g scaffold Post title:string content:text

Dockerfileを作ります。
master.keyを外部から注入できるようにしておきます。

$ touch Dockerfile
Dockerfile
FROM ruby:3.1.2
RUN mkdir /myapp
WORKDIR /myapp
ADD Gemfile /myapp/Gemfile
ADD Gemfile.lock /myapp/Gemfile.lock
RUN bundle install
ADD . /myapp
ARG MASTER_KEY
ENV RAILS_MASTER_KEY=${MASTER_KEY}
# Cloud Run はデフォルトポート8080で起動
EXPOSE 8080
CMD ["bin/rails", "server", "-b", "0.0.0.0", "-p", "8080"]

Cloud Build の設定ファイル cloudbuild.yaml を作成します。
今回はBuildのタイミングでdb:migrateも行います。
また Cloud Run へのデプロイも設定します。

$ touch cloudbuild.yaml
cloudbuild.yaml
steps:
# Cloud Build でビルド
- id: "build image"
  name: "gcr.io/cloud-builders/docker"
  entrypoint: 'bash'
  args:
  - -c
  - |
    docker build \
      -t gcr.io/${PROJECT_ID}/${_SERVICE_NAME} \
      . \
      --build-arg MASTER_KEY=$$MASTER_KEY
  secretEnv:
  - MASTER_KEY
# Container Registry にアップロード
- id: "push image"
  name: "gcr.io/cloud-builders/docker"
  args:
  - push
  - gcr.io/${PROJECT_ID}/${_SERVICE_NAME}
# db:migrate
- id: "apply migrations"
  name: "gcr.io/google-appengine/exec-wrapper"
  entrypoint: "bash"
  args:
  - -c
  - |
    /buildstep/execute.sh \
      -i gcr.io/${PROJECT_ID}/${_SERVICE_NAME}\
      -s ${PROJECT_ID}:${_REGION}:${_INSTANCE_NAME} \
      -e MASTER_KEY=$$MASTER_KEY \
      -- bundle exec rails db:migrate
# Cloud Run デプロイ
- id: 'deploy'
  name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'
  entrypoint: 'bash'
  args:
  - -c
  - |
    gcloud run deploy $_SERVICE_NAME \
      --image gcr.io/${PROJECT_ID}/${_SERVICE_NAME} \
      --region asia-northeast1 \
      --add-cloudsql-instances ${PROJECT_ID}:${_REGION}:${_INSTANCE_NAME} \
      --allow-unauthenticated
substitutions:
  _SERVICE_NAME: sample-app-service
  _REGION: asia-northeast1
  _INSTANCE_NAME: sample-app-db-instance
availableSecrets:
  secretManager:
  - versionName: projects/$PROJECT_ID/secrets/MASTER_KEY/versions/latest
    env: MASTER_KEY
images:
  - "gcr.io/${PROJECT_ID}/${_SERVICE_NAME}"
timeout: 600s

Cloud SQL と接続する

Cloud SQL を構築していきます。
まずインスタンス、データベース、ユーザーの作成をします。

# DBのインスタンス作成
$ gcloud sql instances create sample-app-db-instance \
    --database-version MYSQL_5_7 \
    --tier db-f1-micro \
    --region asia-northeast1

# データベース作成
$ gcloud sql databases create sample-app-db \
  --instance sample-app-db-instance

# ユーザー作成
$ gcloud sql users create app_user \
  --instance=sample-app-db-instance --password=password

ビルド時に db:migrate を実行するため、Cloud Build のサービスアカウントに Cloud SQL に接続するためのロールを設定します。
Cloud Build はデフォルトでサービスアカウントが作られていますので、WebコンソールのIAMと管理ページを見てサービスアカウント名([XXXXXXXXXX]@cloudbuild.gserviceaccount.com)を確認してください。

# サービスアカウントにロール追加
$ gcloud projects add-iam-policy-binding [PROJECT_ID] \
  --member serviceAccount:[XXXXXXXXXX]@cloudbuild.gserviceaccount.com \
  --role roles/cloudsql.client

Cloud Run のデプロイもできるようにロール設定します。
Cloud Run もデフォルトのサービスアカウントがあるため、WebコンソールのIAMと管理ページを見てサービスアカウント名([XXXXXXXXXX]-compute@developer.gserviceaccount.com)を確認してください。

# cloud build -> cloud run
gcloud projects add-iam-policy-binding [PROJECT_ID] \
  --member serviceAccount:[XXXXXXXXXX]@cloudbuild.gserviceaccount.com \
  --role roles/run.developer

# cloud build -> cloud run
gcloud projects add-iam-policy-binding [PROJECT_ID] \
  --member serviceAccount:[XXXXXXXXXX]-compute@developer.gserviceaccount.com \
  --role roles/iam.serviceAccountUser

最後にアプリ側のデータベース設定をします。
先ほど作成したユーザー、パスワード、データベースを設定します。
socket名もデフォルトでは決まっています( /cloudsql/[PROJECT_ID]/[REGION]/[INSTANCE_NAME]

config/database.yml
default: &default
  adapter: mysql2
  encoding: utf8mb4
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: app_user
  password: password
  host: localhost
  socket: /cloudsql/[PROJECT_ID]:asia-northeast1:sample-app-db-instance

development:
  <<: *default
  database: sample-app-db
...

Secret Manager を利用する

環境変数に設定するような秘匿情報を Secret Manager で管理します。
Cloud Build, Cloud Run どちらからもアクセスが可能です。
特に Cloud Run の Railsアプリからアクセスするときは、コードを変更することなく ENV('xxx')で参照することができます。

master.keyのシークレットを作成します。

# シークレットを作成
$ gcloud secrets create MASTER_KEY \
  --data-file config/master.key

Cloud Buildからアクセスできるようにロールを設定します。

# サービスアカウントにロール追加
$ gcloud projects add-iam-policy-binding [PROJECT_ID] \
  --member serviceAccount:[XXXXXXXXXX]-compute@developer.gserviceaccount.com \
  --role roles/secretmanager.secretAccessor

Cloud Run からアクセスできるようにロールを設定します。

# サービスアカウントにロール追加
$ gcloud projects add-iam-policy-binding [PROJECT_ID] \
  --member serviceAccount:[XXXXXXXXXX]@cloudbuild.gserviceaccount.com \
  --role roles/secretmanager.secretAccessor

Cloud Logging を利用する

Cloud Run でアプリを動かすとデフォルトで Cloud Logging にログを出力するようになっています。そのため、特に設定することはないです(便利)
Google Cloud のWebコンソールから Cloud Logging のページを見て、ログが出力されていることを確認してください。

ビルド & デプロイ

ここまでを手動でビルド & デプロイして実行を動作を確認します。

# ビルド、アップロード、デプロイ
$ gcloud builds submit .

Cloud Build と GitHub を連携する

最後に GitHub に pushした タイミングでビルド & デプロイを実行するようにします。
Cloud Build のトリガー機能を使えば簡単に実現できます。

Cloud Build GitHub アプリを選択して、GitHub アカウントを選べばリポジトリが連携されます。
image.png

あとはイベントを設定して、ブランチに push したときに、Cloud Build が実行されれば設定完了です。
image.png

まとめ

今回は以下の構成で構築しました。
Untitled-2022-11-29-2139.png
小さなアプリであれば、十分運用できると思います。
他にも画像ファイルの保存先に Cloud Storage を使ったり、複数のアプリサーバーを使うために Cloud Load Balancing を使ったりできるので、他の構成も試していきたいと思います。

8
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
0