株式会社エイチームフィナジーの@okonomiです。
この記事はAteam Finergy Inc. × Ateam Wellness Inc. Advent Calendar 2023の2日目の投稿です。
普段の業務ではCloud RunにRailsアプリをデプロイして運用しています。
検証のためにテストアプリを作ってCloud Runにデプロイすることがときどきあって、毎回調べながらやってる気がするので最低限の手順をまとめておこうと思います。
今後のアップデートで手順が変わるかもしれないので2023年版としています。
今回デプロイするアプリは手順をシンプルにするためアクセス制限を設けていません。URLが分かれば誰でもアクセスできます。公開してはいけない情報を含めないようにしてください。
環境など
いずれも記事作成時点での最新バージョンです。
- Ruby 3.2.2
- Rails 7.1.2
- Google Cloud CLI 455.0.0
また、デプロイするRailsアプリはproductionモード(RAILS_ENV=production)で動作するように設定していきます。
準備
事前にGoogle Cloud CLIのセットアップを完了しておいてください。
手順
Railsアプリを新規作成してCloud Runサービスにデプロイしてブラウザでアクセスするところまで確認していきます。
Railsアプリ作成
まずはRailsアプリを作ります。
適当なディレクトリを作ったあと
mkdir rails-on-cloud-run
cd rails-on-cloud-run
rails
コマンドをセットアップしてから
bundle init && bundle add rails --skip-install && bundle install --path=.bundle -j4
rails new
を実行します。
bundle exec rails new . -f
今回はデプロイ手順の確認が目的なので、設定は無指定でデフォルトのままにしています。
Railsアプリを作るときに個人的にいつも使ってるワンライナーです。
いろんなやり方があると思いますが、依存gemを含めてディレクトリ内で完結させたいのでこんなふうにしています。
Cloud Runのホストをアクセス許可
Cloud Runのホスト名をホワイトリストに追加します。
# Enable DNS rebinding protection and other `Host` header attacks.
# config.hosts = [
# "example.com", # Allow requests from example.com
# /.*\.example\.com/ # Allow requests from subdomains like `www.example.com`
# ]
+ config.hosts = [
+ /.*\.run\.app/
+ ]
end
意図しないホスト名によるリクエストを弾くため、ホスト名を明示的に指定する必要があります。
Cloud RunサービスのURLは.run.app
のドメインになります。
トップページを設定
いまのままだと表示するページがなくてアクセスするとエラーになってしまうので、ページを追加します。
なんでもいいですが、ここではお手軽にRailsのWelcomeページを設定しておきます。
Rails.application.routes.draw do
# Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html
# Reveal health status on /up that returns 200 if the app boots with no exceptions, otherwise 500.
# Can be used by load balancers and uptime monitors to verify that the app is live.
get "up" => "rails/health#show", as: :rails_health_check
# Defines the root path route ("/")
# root "posts#index"
+ root "rails/welcome#index"
end
RailsのWelcomeページはproductionでは表示されないので、明示的にルーティングに追加する必要があります。
Cloud Runサービスにデプロイ
ここまででアプリの設定は完了しました。
次はgcloud run deploy
でCloud Runサービスにデプロイします。
gcloud run deploy rails-on-cloud-run \
--source . \
--project advent-calendar-2023 \
--region asia-northeast1 \
--allow-unauthenticated \
--set-env-vars RAILS_MASTER_KEY=$(cat config/master.key)
初めて実行したときはAPIの有効化などの質問が出るので、内容を確認しつつ回答していきます。
実行完了まで数分かかるのでしばらく待ちます。正常に完了すると実行結果の最後に作成されたCloud RunサービスのService URLが出力されているはずです。そのURLにブラウザでアクセスするといつものRailsのWelcomeページが表示されます。
以上でRailsアプリをCloud Runにデプロイできました。
gcloud run deploy SERVICE --source .
でソースコードからCloud Runサービスにデプロイします。
このコマンドを実行すると、Cloud Buildによるコンテナイメージのビルド、Artifact Registryへのコンテナイメージのpush、そのコンテナイメージを使ってCloud Runサービスを作成・デプロイ、といった一連の作業が自動的に行われます。
コンテナのRAILS_MASTER_KEY
環境変数にconfig/master.key
の内容を設定しておきます。
RAILS_MASTER_KEY
環境変数もしくはconfig/master.key
はconfig/credentials.yml.enc
の複号化に必要になります。
config/credentials.yml.enc
にはsecret_key_base
の値が記載されており、secret_key_base
が見つからないと次のようなエラーでアプリの起動に失敗します。
/usr/local/bundle/ruby/3.2.0/gems/railties-7.1.2/lib/rails/application.rb:655:in `validate_secret_key_base': Missing `secret_key_base` for 'production' environment, set this string with `bin/rails credentials:edit` (ArgumentError)
secret_key_base
の設定は、config/credentials.yml.enc
のほかにもSECRET_KEY_BASE
環境変数などいくつかの方法があります。
備考: リクエストを待ち受けるポートは自動設定される
Cloud RunサービスのコンテナはPORT
環境変数で定義されたポートでリクエストを待ち受けるようにする必要があります。
参考: コンテナを構成する | Cloud Run のドキュメント | Google Cloud
Cloud Runサービスのリビジョンで設定したコンテナポートがPORT
環境変数に設定されます。リビジョンでコンテナポートを特に指定しなければデフォルト値が設定されます。
RailsはPORT
環境変数が定義されていればそれを参照します。
def port
options[:port] || ENV.fetch("PORT", DEFAULT_PORT).to_i
end
なのでCloud Runサービスにデプロイするときは、とくになにもしなくても自動的にリビジョンで指定されたコンテナポートでRailsアプリがリクエストを待ち受けてくれます。
まとめ
Cloud Runへのデプロイ手順をまとめました。
今回手順をまとめてみて、ひと昔前にCloud Runを触り始めたときに比べてデプロイが格段に楽になったと感じました。
Rails 7.1からrails new
でDockerfile
が生成されるようになったのと、Cloud Runのソースデプロイが可能になったのが大きいです。
どちらも実サービスを構築するときはそれなりにカスタマイズすることになると思いますが、今回のようにとりあえずアプリをデプロイしてみたいときにはとても助かりました。