GCPに興味はあるけれど、DB料金がお高くて個人開発には厳しいな。。。と思っていたところ、
というTweetに出会いました。個人開発のコストはDB次第 - laiso https://t.co/rL8qYmafuv ここ最近は SQLite + Litestream という選択肢をとれば良いと思ってる。https://t.co/nR5BObiBtu
— V (@voluntas) 2022年5月5日
SQLite + Litestreamでお安くGCPにデプロイできるというのです。
自分のような初心者には難度が高いかと思いましたが、先人の資料が充実していたので、挑戦してみることにしました。
目次
- 目次
- 環境
- 設定
- Dockerfileの作成
- entrypoint.shファイルの作成
- Litestreamの設定ファイルの作成
- .gcloudignore ファイルの作成
- デプロイ
- 動作確認
- 古いデータの削除
- 参考サイト
- ソースコード
環境
- wsl2
- Debian 11.5
- Ruby 3.1.1
- Rails 7.0.4
- React 18.2.0
- SQLite3 3.34.1
- Docker 20.10.21
- Google Cloud SDK 412.0.0 alpha 2022.12.09 beta 2022.12.09 bq 2.0.83 bundled-python3-unix 3.9.12 core 2022.12.09 gcloud-crc32c 1.0.0 gsutil 5.17
設定
Googleアカウント
- アカウントを用意します
- アカウントに二要素認証を設定します
Cloud Strageのバケットを作成
- 公式ドキュメントを参考に、コンソールからCloud Storage のバケットを作成します
バケットの作成 | Cloud Storage | Google Cloud
Google Cloudの設定
Cloud SDKを WSL2 の Debian にインストールします
gcloud CLI をインストールする | Google Cloudgcloud init --console-only
でCloudSDKを初期化します
gcloud CLI の初期化 | Google Cloud CLI のドキュメント
Dockerfileの作成
Dockerfile
を作成します
FROM ruby:3.1.1 ENV RAILS_ENV="production" ENV NODE_ENV="production" # Cloud Run default port 8080 EXPOSE 8080 # nodeをインストール RUN curl -fsS https://deb.nodesource.com/setup_16.x | bash - && apt-get install -y nodejs # APTライブラリを更新してインストール # aptキャッシュをクリーンする。yオプションですべての問い合わせにyes # /var/lib/apt/lists/*を削除してイメージを減らす # https://docs.docker.jp/engine/articles/dockerfile_best-practice.html RUN apt-get update \ && apt-get install -y --no-install-recommends sqlite3 \ && apt-get -y clean \ && rm -rf /var/lib/apt/lists/* # Download the static build of Litestream directly into the path & make it executable. # This is done in the builder and copied as the chmod doubles the size. # ref: https://github.com/steren/litestream-cloud-run-example/blob/main/Dockerfile ADD https://github.com/benbjohnson/litestream/releases/download/v0.3.9/litestream-v0.3.9-linux-amd64-static.tar.gz /tmp/litestream.tar.gz RUN tar -C /usr/local/bin -xzf /tmp/litestream.tar.gz # working directoryの設定 WORKDIR /app # リポジトリのファイルをコピー COPY . /app # gemのインストール RUN bundle install # アセットをプリコンパイルする # コンパイルが終わったら不要なキャッシュと node_modules を消してイメージの容量を減らす RUN SECRET_KEY_BASE=placeholder bundle exec rails assets:precompile \ && rm -rf node_modules tmp/cache # Copy Litestream configuration file & startup script. COPY ./litestream.yml /etc/litestream.yml COPY entrypoint.sh /app/entrypoint.sh RUN chmod +x /app/entrypoint.sh # public配下のファイルを公開する ENV RAILS_SERVE_STATIC_FILES="true" ENTRYPOINT ["/app/entrypoint.sh"]
entrypoint.shファイルの作成
entrypoint.sh
ファイルを作成します
#!/bin/bash set -e # コンテナ起動時に持っているSQLiteのデータベースファイルは、 # 後続処理でリストアに成功したら削除したいので、リネームしておく if [ -f /app/db/production.sqlite3 ]; then mv /app/db/production.sqlite3 /app/db/production.sqlite3.bk fi # Restore the database - litestream restore -v -if-replica-exists -config /etc/litestream.yml /app/db/production.sqlite3 # リストアに成功したら、リネームしていたファイルを削除 if [ -f /app/db/production.sqlite3]; then echo "---- Restored from Cloud Storage ----" rm /app/db/production.sqlite3.bk else # 初回起動時にはレプリカが未作成であり、リストアに失敗するので、 # その場合には、冒頭でリネームしたdbファイルを元の名前に戻す echo "---- Failed to restore from Cloud Storage ----" mv /app/db/production.sqlite3.bk /app/db/production.sqlite3 fi # server.pidが残ってしまって起動できなくなることを防ぐために削除する # server.pid は、削除してもrails serverを実行した時に自動で作成される rm -f /app/tmp/pids/server.pid # Run litestream with your app as the subprocess. exec litestream replicate -exec "rails server -p 8080 -b 0.0.0.0"
Litestreamの設定ファイルの作成
dbs: - path: /app/db/production.sqlite3 replicas: - url: gcs://kankendb
.gcloudignore ファイルの作成
- Cloud Runではコピー対象外のファイルは
.gcloudignore
ファイルで指定します
.gcloudignore
は、.gitignore
に指定されているファイルも無視するので注意が必要ですが、
This .gcloudignore (similar to the one generated when Git files are present) would prevent the upload of the .gcloudignore file, the .git directory, and any files in ignored in the .gitignore file:
gcloud topic gcloudignore | Google Cloud CLI Documentation
.gcloudignore
で一旦全部 ignore して、必要な特定のファイルやディレクトリだけを指定すれば、実行に必要ないファイルをアップロードせずに済みます
.gcloudignore で全部無視して必要なものだけ指定する - ぽ靴な缶
# ignore all * # directories !app !bin !config !db !frontend !lib !node_modules !public !storage !vendor # ignore directories frontend/src/__tests__ # files !Dockerfile !entrypoint.sh !Gemfile !Gemfile.lock !package.json !package-lock.json !config.ru !identifier.sqlite !litestream.yml !postcss.config.cjs !Procfile.dev !Rakefile !tailwind.config.cjs !tsconfig.json !tsconfig.node.json !vite.config.ts
デプロイ
- 以下のコマンドでデプロイします
gcloud beta run deploy kanken-practice \ --source . \ --set-env-vars REPLICA_URL=gcs://kankendb/database \ --max-instances 1 \ --execution-environment gen2 \ --no-cpu-throttling \ --allow-unauthenticated \ --region asia-northeast1 \ --project keikami
引数は
- Litestreamは複数サーバとの互換性が無いため、最大1インスタンスにする
- Cloud Run の第2世代を使用する
- CPUが常に割り当てられるようにする
- 認証されていない呼び出しを許可することで、サービスにアクセスできるようにする
の設定です
gcloud run deploy | Google Cloud CLI Documentation
GitHub - steren/litestream-cloud-run-example: An example of using Litestream within Cloud Run
デプロイ開始
⠛ Building and deploying... Uploading sources. ⠛ Uploading sources... . Building Container... . Creating Revision... . Routing traffic... . Setting IAM Policy...
成功したようです
Done. Service [kanken-practice] revision [kanken-practice-00159-jis] has been deployed and is serving 100 percent of traffic. Service URL: https://kanken-practice-b5ve7zdnrq-an.a.run.app
動作確認
- 動作が確認できました
古いデータの削除
Cloud Run にデプロイすると、Cloud StorageやArtifact Registryに都度オブジェクトが生成されます
そのままにしておいても削除されず、課金対象になってしまうので、古いデータを削除しますCloud Storage
Artifact Registry
自動化するには
オブジェクトのライフサイクル管理 | Cloud Storage | Google Cloud
画像を管理 | Artifact Registry のドキュメント | Google Cloud
参考サイト
- Replicating to Google Cloud Storage - Litestream
- アセットパイプライン - Railsガイド
- 【Ruby on Rails】アセットパイプラインについて | プログラミングマガジン
- CloudRun + Litestream で Rails アプリを激安で公開する - Qiita
- SQLite + Litestream + CloudRun で「個人開発並みの予算でもSQLを捨てない」バックエンド構築(Next.jsを例にして) - Qiita
- Djangoアプリを、Coogle Cloud の Cloud Run + Cloud Storage + Litestream な環境で動かしてみた - メモ的な思考的な
- HerokuからCloud Run + Litestreamへ移行した - memo.yammer.jp
- Cloud Functions for Firebaseの利用で、異様にGCPのStorageが消費されると思ったら..
- Dockerfileにおけるキャッシュの削除 - ばいばいバイオ
- Dockerfileのapt-getでよく見るあの呪文について | DevelopersIO