結論
- Quick Startに出てくるCloud Buildも少し知ってた方がいい
- Cloud SQL使うならCloud SQL Proxy対応してるので、そのオプションを使う
- インフラにコスト払いたくない、手抜きしたい人には最高のサービス
実際のアプリケーションを使う場合を想定して使う
Cloud RunのQuickStart的な記事や内容をよく見ますが、バックエンドで使うならCloud SQLは当たり前に出てくると思う。
なんでCloud SQL(Proxy)と繋ぐ方法は知ってると吉なので書いておきます。
アプリケーションの作成
今回はRailsでサクッと作ってみるということで
$ rails new rails_on_cloud_run -T -d postgresql
でまずはサクッとRailsプロジェクトを作ります。
Dockerfileおよびstartファイル作成
Cloud RunはDockerコンテナで動くので、Dockerfile
が必須です。そのDockerコンテナの起動に使うstart
ファイルを一緒に作ります。
FROM ruby:2.6.3-alpine
RUN apk add --no-cache tzdata postgresql-dev && \
cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
RUN mkdir /app
WORKDIR /app
ARG BUNDLE_OPTIONS
COPY Gemfile /app/Gemfile
COPY Gemfile.lock /app/Gemfile.lock
RUN apk add --no-cache --virtual .rails-builddeps alpine-sdk && \
bundle install -j4 ${BUNDLE_OPTIONS} && \
apk del .rails-builddeps
COPY . /app
CMD ["bin/start"]
手抜きのようで必要最低限のDockerfile
。かくゆう私は基本このDockerfile
から始めます。
で最後のCMD
に書いてるstart
ファイルを作ります。
#!/bin/sh
RAILS_PORT=3000
if [ -n "$PORT" ]; then
RAILS_PORT=$PORT
fi
# db migrate
# TODO 後でJobに切り出したい
bin/rails db:create
bin/rails db:migrate
bin/rails s -p $RAILS_PORT -b 0.0.0.0
ここで大事なのはPORT
という環境変数があったら、そのポートでRailsを起動していること。
Cloud RunではPORT
という環境変数が渡ってきて、そのポートで起動してるかのチェックが行われます。なので指定されたポートで起動する必要があるため、このような記載になっています。
Cloud SQLへの接続設定
ここまでで確かにビルドはできるのですが、もう1つ大切なことがあります。
それはCloud SQLへ繋ぐための設定です。Cloud SQLへの接続はCloud SQL Proxyを介して接続することが推奨されています。(もちろんなくてもできますが)
そこでそのCloud SQL Proxyを使うためにDatabase接続の定義を修正します。Railsの場合はdatabase.ymlなので例として
default: &default
adapter: postgresql
encoding: utf-8
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
host: <%= ENV['DB_HOST'] || 'localhost' %>
username: <%= ENV['DB_USERNAME'] %>
password: <%= ENV['DB_PASSWORD'] %>
port: <%= ENV['DB_PORT'] %>
# socket: <socket path> # for MySQL
production:
<<: *default
database: <your database name>
単に環境変数から取得しているのですが、大事なのは接続先です。Cloud SQL Proxy対応のCloud Runコンテナはコンテナ内の/cloudsql/<Cloud SQL instance>
にsocketがあるのでそこに向けて接続する必要があります。PostgreSQLの場合は上記のyamlファイルのhost部分をそれに指定し、MySQLの場合はsocket部分を指定できるようになればいいです。
ちなみにそのDB_HOST
の指定は/cloudsql/<Project ID>:<region>:<Cloud SQL Instance name>
になると思います。
もしCloud SQLへの接続名がわからないならConsoleからはこんな感じで見えるはずです。
Cloud Build(Docker build)の設定
上記に記載したリンクのQuick Startにgcloud builds submit
というコマンドが出てくるが、これがDockerイメージをビルドするためのサービスを起動するコマンドです。
そのコマンドを使うと確かにビルドできるのですが、Production等で使用する場合にビルド時間の短縮とかを考える必要あります。そこでCloud Buildではkanikoが使えます。kanikoはビルドする時に前回のビルド時キャッシュを使用してビルドすることでビルド時間を短縮します。(詳しくは説明しませんので、ググって下さい)
kanikoを使うで最低限必要なyamlファイル
steps:
- name: 'gcr.io/kaniko-project/executor:latest'
args:
- --build-arg=BUNDLE_OPTIONS=--without development test
- --destination=gcr.io/<Project ID>/<image name>:latest
- --cache=true
name
にkanikoを使うイメージ名を指定することで使用することが可能です。使える引数とかはkanikoのドキュメントを見れば大体わかると思います。必要なのはcache
とdestination
。cache
は前回ビルドのキャッシュを使うかどうか、destination
はビルドしたイメージをどのリポジトリに登録するかの指定です。
build-arg
については上記のDockerfile
でARGを指定していた部分があります。Railsの場合はProductionでは不要なgemのインストールを避けるためにこんな感じで逃げることができます。
このyamlファイルを指定して実行するには
$ gcloud builds submit --project <Project ID> --config ./cloudbuild.yml
で実行すればOKです。project
を付けてるのは自分の場合は複数プロジェクトを使用する場合があるので、ほぼほぼ必死なので付けてるだけです。
ちなみにこのkanikoを使うなら以下のコマンドを叩いてkanikoの使用を有効化する必要があります。
$ gcloud config set builds/use_kaniko True
Cloud Runのデプロイ
ここまで来たら最後はデプロイです。
デプロイの時に大切なのは、Cloud SQL Proxyを使用するオプションを付けることが大事です。
サクッとデプロイコマンドを貼ると
$ gcloud beta run deploy <Cloud run service name> \
--project <Project ID> \
--image gcr.io/<Project ID>/<image name> \
--region us-central1 \
--add-cloudsql-instances <Project ID>:<region>:<Cloud SQL Instance name> \
--set-env-vars RAILS_ENV=production \
--set-env-vars RAILS_MASTER_KEY=<Rails master key> \
--set-env-vars DB_USERNAME=<database user name> \
--set-env-vars DB_PASSWORD=<database password> \
--set-env-vars DB_HOST=/cloudsql/<Project ID>:<region>:<Cloud SQL Instance name>
add-cloudsql-instances
というオプションがCloud Runで実行するコンテナにCloud SQL Proxyを使用するようにしています。これで先程指定したunix socketのファイルが生成されるので、Cloud SQLへ接続できるようになるはずです。
最後に
アプリケーションを使用する上で最低限必要なものを想定して使用すると課題も出てきます。
Cloud Runのbetaリリース当初はCloud SQL Proxyの設定はなく、泣く泣くDockerイメージの中にCloud SQL Proxyをインストールして使っていたのですが、対応されたことにより上記のよう設定だけで完了できるようになりました。
AWSも素晴らしいですが、GCPもこういった素晴らしいサービスが多々あるので、必要なものを取捨選択できるような状態になるのが好ましいですね。
参考URL
https://cloud.google.com/run/docs/quickstarts/build-and-deploy
https://cloud.google.com/run/docs/configuring/connect-cloudsql
https://cloud.google.com/cloud-build/docs/kaniko-cache