Cloud Native Buildpacksを利用してCloud RunにRailsアプリをデプロイ (開発環境: macOS)
はじめに
あるPaaSクラウドで運用していた既存のRailsアプリがあり、それをCloud Native Buildpacksを利用してCloud Runにデプロイして移行します。このRailsアプリはRuby 3.2.0とRails 7.0.4で構成され、データベースにはPostgreSQLを利用しています。開発環境にはmacOSを利用しています。
セットアップ
packコマンドを利用するのでHomebrewでインストールします。
% brew tap buildpacks/tap
% brew install pack
pack builder suggestを実行すると推奨されているbuilderが表示されます。
% pack builder suggest
Suggested builders:
	Google:                gcr.io/buildpacks/builder:v1      Ubuntu 18 base image with buildpacks for .NET, Go, Java, Node.js, and Python                                                      
	Heroku:                heroku/buildpacks:20              Base builder for Heroku-20 stack, based on ubuntu:20.04 base image                                                                
	Paketo Buildpacks:     paketobuildpacks/builder:base     Ubuntu bionic base image with buildpacks for Java, .NET Core, NodeJS, Go, Python, Ruby, Apache HTTPD, NGINX and Procfile          
	Paketo Buildpacks:     paketobuildpacks/builder:full     Ubuntu bionic base image with buildpacks for Java, .NET Core, NodeJS, Go, Python, PHP, Ruby, Apache HTTPD, NGINX and Procfile     
	Paketo Buildpacks:     paketobuildpacks/builder:tiny     Tiny base image (bionic build image, distroless-like run image) with buildpacks for Java, Java Native Image and Go                
Tip: Learn more about a specific builder with:
	pack builder inspect <builder-image>
GoogleのbuilderにはUbuntu 18 base image with buildpacks for .NET, Go, Java, Node.js, and Pythonと表示されRubyがありませんが、現在はRubyもサポートされているようです。
イメージを作成してローカルで実行
Procfileを作成
起動するコマンドをProcfileに記述します。
web: bin/rails server -p $PORT -b 0.0.0.0
run.Dockerfileとbuilder.Dockerfileを作成
PostgreSQLと接続するためにlibpq-devが必要となるため、run.Dockerfileとbuilder.Dockerfileを作成します。
FROM gcr.io/buildpacks/gcp/run:v1
USER root
RUN apt-get update && apt-get install -y --no-install-recommends \
  libpq-dev zlib1g-dev liblzma-dev libxml2-dev libxslt1-dev patch && \
  apt-get clean && \
  rm -rf /var/lib/apt/lists/*
USER cnb
FROM gcr.io/buildpacks/builder:v1
USER root
RUN apt-get update && apt-get install -y --no-install-recommends \
  libpq-dev zlib1g-dev liblzma-dev libxml2-dev libxslt1-dev patch && \
  apt-get clean && \
  rm -rf /var/lib/apt/lists/*
USER cnb
Railsの設定
Railsでアセットをプリコンパイルして、public_file_server.enabledをtrueに設定します。
% rake assets:precompile RAILS_ENV=production
config.public_file_server.enabled = true
イメージの作成
Dockerを起動してからbuilderとrunのイメージを作成します。
% docker build -t my-builder-image -f builder.Dockerfile .
% docker build -t my-run-image -f run.Dockerfile .
packコマンドを実行してイメージを作成します。あとで作成するContainer Registryの情報をタグに追加します。
% pack build my-app \
  --builder my-builder-image \
  --run-image my-run-image \
  --tag gcr.io/project/my-app:latest
Cloud SQL for PostgreSQLのセットアップ
インスタンスの作成
GCPでCloud SQL for PostgreSQLのインスタンスを作成します。今回作成したインスタンスの接続はパブリックIPを選択しました。
ユーザーとデータベースの作成
GCPでCloud SQLのユーザーとデータベースを作成します。
Railsにデータベース接続を設定
EDITOR=vi rails credentials:editを実行してCloud SQLのパスワードを保存します。
cloud_sql:
  password: ************ 
config/database.ymlにCloud SQLへの接続情報を指定します。
production:
  <<: *default
  database: my_app_production
  username: my_app
  password: <%= Rails.application.credentials.cloud_sql[:password] %>
  host: /cloudsql/project:region:instance-name
% gcloud sql connect instance-name --user dbuser --database dbname
データベースのリストア
バックアップファイルの作成
pg_dumpでバックアップファイルを作成します。
% pg_dump -c --no-acl --no-owner app_development > app.sql
バックアップファイルのアップロード
作成したデータベースに既存アプリのデータベースをリストアします。Cloud Shellでバックアップしたファイルをアップロードします。
Cloud SQL Auth Proxyのセットアップ
Cloud ShellでCloud SQL Auth Proxyを利用できるようにします。
% wget https://dl.google.com/cloudsql/cloud_sql_proxy.linux.amd64 -O cloud_sql_proxy
% chmod +x cloud_sql_proxy
Cloud SQL Auth Proxyの起動
以下のコマンドでCloud SQL Auth Proxyを起動します。project region instance-nameの部分はCloud SQLのインスタンスの情報を入力します。
% ./cloud_sql_proxy -instances=project:region:instance-name=tcp:5432 &
リストアの実行
psqlでデータベースをリストアします。
% psql -U dbuser -d dbname -h 127.0.0.1 < backup.dump
バックアップのファイル形式によってはpg_restoreなど別の方法でリストアする必要があります。
Cloud Runにデプロイ
Container Registryに登録
% gcloud auth configure-docker
% docker push gcr.io/project/my-app:latest
Cloud Runへのデプロイ
gcloudコマンドでCloud Runにデプロイします。環境変数にRAILS_ENVを指定しています。
% gcloud run deploy my-app \
  --image=gcr.io/project/my-app \
  --region asia-northeast1 \
  --platform managed \
  --allow-unauthenticated \
  --set-env-vars RAILS_ENV=production
Cloud SQLの接続を設定
GCPでCloud Runのインスタンスのページにある新しいリビジョンの編集とデプロイからCloud SQLの接続を追加します。
おわりに
Cloud Native Buildpacksを利用してRailsアプリをCloud Runにデプロイをすることができました。開発環境も運用環境もDockerを使うという人もいると思いますが、私の場合はmacOSのHomebrewで開発環境を構築して、運用環境だけコンテナを使うという感じなので、そういう人にとってはCloud Native Buildpacksを利用したデプロイというのは簡単でよいかと思いました。
Discussion