🍔

TurborepoのリモートキャッシュサーバをCloud RunとGCSで構築する

2022/07/24に公開

モチベーション

Turborepoを使用する目的はいくつかありますが、リモートキャッシュが一番大きいと個人的には思っています。
リモートキャッシュを使用することで、CIの高速化やチームメンバーのローカルでの開発体験向上にもつながります。

リモートキャッシュを導入する最も簡単な方法は、Vercelを利用することですが、チームでとなるとアカウント管理や料金など問題が発生します。

アカウントレスなチーム専用のリモートキャッシュサーバをセルフホストし、上記の問題を解消することが本稿のモチベーションです。

なお、Turborepoの紹介や導入・使用方法に関しては説明を省きますので、詳しく知りたい方は公式サイトドキュメント、下記のmizchiさんの記事などを参照してください。

https://zenn.dev/mizchi/articles/introduce-turborepo

リポートキャッシュサーバのセルフホスト

公式ドキュメントでVercel以外のリモートキャッシュサーバとの連携について明記されています。

You can self-host your own Remote Cache or use other remote caching service providers as long as they comply with Turborepo's Remote Caching Server API.

TurborepoのリモートキャッシュサーバAPIに準拠していれば、リモートキャッシュのセルフホスティングや、他のリモートキャッシュサービスプロバイダを利用することも可能です。

肝心のリモートキャッシュサーバAPIに関しては、クライアントコードがリンクされており、「クライアントコード読んで、それに準拠するように自分で構築しろ」といった少々雑な感じですが、有志の方々がセルフホスト用のDockerイメージやサーバーコードを公開してくれていますので、今回はそれを使用します。

ちなみに、Cloudflare WorkerとKVで構築するという面白いプロジェクトも中には存在しています。
(KVのValue size limitが最大25MB(1オブジェクトあたり)なので、そこだけ心配ですが...)

https://github.com/msutkowski/turborepo-remote-cache-api-cf-kv

構成

今回はfox1t/turborepo-remote-cacheというDockerイメージと、GCPのCloud RunとGCS(Google Cloud Storage)を使用して構築します。

2022/07/23現在、fox1t/turborepo-remote-cacheのドキュメントでは、GCSのサポートは未対応であると記載されています。

  • Local filesystem
  • AWS S3
  • Azure Blob Storage (WIP)
  • Google Cloud Storage (WIP)
  • Google Drive Blobs (WIP)

しかし、内部的にはS3クライアントのNode SDKが使用されているため、問題なくGCSに接続可能です。

https://zenn.dev/mizchi/articles/s3-compatible-client

セットアップ

GCS

まず、キャッシュストレージ用のGCSバケットを作成します。

ライフサイクルルールの設定し、古くなったキャッシュを自動的に削除して無駄コストの抑制をしましょう。(期間は適宜調整してください。)

そしてHMACキーを取得します。
前述の通り、今回利用するDockerイメージではS3クライアントが利用されているため、Cloud Run起動時のサービスアカウントによる自動接続は、残念ながら利用できません。

https://cloud.google.com/storage/docs/authentication/managing-hmackeys?hl=ja

アクセスキーとシークレットをコピーしておきます。

Cloud Run

Docker HubのイメージはそのままではCloud Runで利用できないので、GCRにプッシュしておきます。
Cloud Shellを開いて下記を実行してください。

docker pull fox1t/turborepo-remote-cache:latest
docker tag fox1t/turborepo-remote-cache:latest gcr.io/sandbox-353309/fox1t/turborepo-remote-cache:latest
docker push gcr.io/YOUR_PROJECT_ID/fox1t/turborepo-remote-cache:latest

次に、Cloud Runのコンソールを開き、新しいサービスを作成します。

「変数とシークレット」は次のように設定します。 波括弧で囲っているところを適宜変更してください。
ところどころAWS_XXXとかs3となっているところがありますが、ミスではありません。

NODE_ENV: production
TURBO_TOKEN: {適当な文字列}
AWS_ACCESS_KEY_ID: {HMACアクセスキー}
AWS_SECRET_ACCESS_KEY: {HMACシークレット}
S3_ENDPOINT: https://storage.googleapis.com
AWS_REGION: auto
STORAGE_PROVIDER: s3
STORAGE_PATH: {作成したGCSのバケット名}

作成が完了したらエンドポイントをコピーしておきます。

これでセットアップは完了です。

truboコマンドから接続する

ドキュメントにあるように turbo run コマンドに --api --token --team をつけて実行することで、セルフホストしたキャッシュサーバに接続できます。

https://turborepo.org/docs/reference/command-line-reference#turbo-run-task

turbo run build --token={TURBO_TOKEN} --api={Cloud Runのエンドポイント} --team={適当なチーム名}

--token--team に関しては、オプション引数ではなく、環境変数 TURBO_TOKEN TURBO_TEAM で渡すことも可能です。

実際に実行してみます。

初回はキャッシュがないため、ビルド完了までにおおよそ10秒ほど時間を要しています。

続いて2回目。
(ローカルのキャッシュを消してから実行します。rm -rf node_modules/.cache/turbo)

リモートキャッシュが参照できたので、1秒でビルド(リストア)が完了しました。

実際にGCSのコンソールで確認すると、--team=で渡しているチーム名でキャッシュが生成されていることが確認できます。


以上です。Happy Turborepo Life🎉

GitHubで編集を提案

Discussion