本文へ移動
Step 06 · Runtime + Secret

Cloud Run + Artifact Registry + Secret ManagerRun, store, secret

松葉のアプリ本体を動かす Cloud Run(コンテナを HTTP リクエスト毎に起動するサーバレス基盤)の 4 サービスを「ハロー世界」イメージで先に空デプロイし、コンテナイメージの保管庫 Artifact Registry と、認証情報の金庫 Secret Manager(7 シークレット)を整備しました。

所要時間: 30 分 前提条件: Step 00〜04 後続: Step 07 / 08 / 09
01

Cloud Run × 4 サービスを空デプロイFour services, placeholder image

後続手順(08 の Pub/Sub サブスクリプション、09 の LB バックエンド)が Cloud Run の URL を必要とするため、本物のアプリイメージができる前に、空のハロー世界イメージ gcr.io/cloudrun/hello で先にサービス枠を作成しました。後で同じサービス名に本物のイメージを上書きデプロイしても URL は維持されます。

サービスmin / maxリソース役割外部公開
matsuba-web1 / 上限ありCPU・メモリを設定Next.js 16 の UI(画面)LB 経由のみ
matsuba-api1 / 上限ありCPU・メモリを設定Hono の業務 API + 認証LB 経由のみ
matsuba-sync0 / 上限ありCPU・メモリを設定Go の Drive 同期ワーカー(Pub/Sub 経由でのみ起動)internal(外部不可)
matsuba-scanner1 / 上限ありCPU・メモリ(大きめ)を設定Go + ClamAV のウイルススキャンinternal(外部不可)

min=1 / min=0 の意味: min=1 は「常に 1 インスタンス(コンテナ)が起動した状態を保つ」、min=0 は「リクエストが来るまで完全停止」。matsuba-sync は需要連動なので min=0(アイドル時 0 円)、ウイルススキャンは初動を遅らせないため min=1 で常時待機。

02

Artifact Registry(コンテナイメージ保管庫)Container registry

コンテナイメージ(アプリを丸ごとパッケージ化したもの)を保管する場所です。GitHub Actions がビルドしたイメージをここに push し、Cloud Run がここから pull します。

項目値
名前matsuba
形式 / モードDocker · Standard
ロケーションasia-northeast1(東京)
フルパスasia-northeast1-docker.pkg.dev/<project-id>/matsuba
クリーンアップポリシー一定期間経過 + 最新の一定数を保持して自動削除(コスト膨張対策)
03

Secret Manager に登録した 7 シークレットSeven secrets

パスワード・API キー・暗号鍵などをアプリのソースコードに書かず、Secret Manager(クラウドの金庫)に置きました。Cloud Run はサービスアカウントの権限で実行時に取り出します。命名は matsuba-{key} で統一しています。

Secret 名中身誰が読めるか
matsuba-database-urlSupabase Postgres の接続文字列api の実行 SA / batch(Jobs)の実行 SA
matsuba-better-auth-secretセッション署名鍵(32 byte random)api の実行 SA
matsuba-google-client-idGoogle OAuth クライアント IDapi の実行 SA
matsuba-google-client-secretGoogle OAuth クライアント Secretapi の実行 SA
matsuba-resend-api-keyResend API キーapi の実行 SA / batch(Jobs)の実行 SA
matsuba-resend-webhook-secretResend Webhook 署名検証鍵api の実行 SA
matsuba-cors-origin許可する Origin(https://portal.example.com)api の実行 SA / web の実行 SA

SA 単位 × Secret 単位の最小権限: 「scanner の実行 SA にはどの Secret も渡さない」「隔離読取専用 SA には何も渡さない」「api の実行 SA には隔離操作の鍵を渡さない」など、SA とシークレットの関係をリソース単位で絞っています。プロジェクト全体に secretAccessor を付けるショートカットは取りません。年次の手動ローテーションをカレンダー管理で行います。

04

イメージ → 実行 → シークレット注入の流れImage-to-runtime flow

図 · イメージ build → 保管 → Cloud Run でシークレット注入して起動
GitHub ActionsCloud Build でイメージ作成Artifact Registrymatsuba/{service}:{sha}Cloud Run Revision新リビジョン作成本番起動トラフィック 100%pushdeploySecret Manager · 7 シークレットmatsuba-database-url / better-auth-secret / google-client-id / -secretresend-api-key / resend-webhook-secret / cors-originSA 単位の最小権限で参照起動時に --update-secrets で注入古いイメージは期間と上限数で自動削除

本構築時点では gcr.io/cloudrun/hello という Google 公式のハロー世界イメージが入っており、本物のアプリイメージは Step 1 以降の機能タスクで GitHub Actions の CI/CD ワークフローから順次上書きデプロイされます。URL は変わらないため、08 で作るサブスクリプションや 09 で作る LB は本手順完了時点で確定値として参照できます。