🔨

Cloud Native Buildpacksを利用してCloud RunにRailsアプリをデプロイ (開発環境: macOS)

2022/10/24に公開

はじめに

ある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もサポートされているようです。

https://github.com/GoogleCloudPlatform/buildpacks

イメージを作成してローカルで実行

Procfileを作成

起動するコマンドをProcfileに記述します。

Procfile
web: bin/rails server -p $PORT -b 0.0.0.0

run.Dockerfileとbuilder.Dockerfileを作成

PostgreSQLと接続するためにlibpq-devが必要となるため、run.Dockerfilebuilder.Dockerfileを作成します。

run.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
builder.Dockerfile
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.enabledtrueに設定します。

% rake assets:precompile RAILS_ENV=production
config/environments/production.rb
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への接続情報を指定します。

config/database.yml
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

https://cloud.google.com/sql/docs/postgres/connect-admin-proxy?hl=ja#install-the-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など別の方法でリストアする必要があります。

https://cloud.google.com/sql/docs/postgres/import-export/import-export-dmp

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