v1
比較検討案

インフラ構成(Google Cloud 案)

実査機能 新基盤のインフラ構成の Google Cloud 案。Cloudflare 軸は不採用が決定したため、比較対象は AWS 統一案コンピュート=Cloud Run(従量・常駐ゼロ)/データ永続=同一クラウド・東京リージョン(国内保管)/メディア・データ配信=LiveKit Cloud の 2 社構成。評価軸は AWS 案と同一(①アイドル時固定費最小 ②運用対象最小 ③データレジデンシ ④既存運用資産との統合)。

1. 決定サマリ

領域決定(GCP 案)AWS 案との差・備考
基盤コア API採用 Cloud Run(Hono + @hono/zod-openapi + Prisma 7・Node 22)AWS: API Gateway + Lambda(関数分割・アダプタ経由)。Cloud Run はコンテナ 1 サービスに API / queue / cron / workflows の 4 役を同居でき、Hono アプリを 1 つの HTTP サーバーのまま動かせる。min-instances=1 でコールドスタート対策(AWS 案のプレウォーム / Provisioned Concurrency 相当)
DB採用 Cloud SQL for PostgreSQL(db-g1-small・東京)AWS: RDS db.t4g.micro(~$25)。Cloud SQL db-g1-small は割高(~$45=インスタンス $33.58 + SSD 50GB $11.05)。SLA は両者とも最小クラスでは実効外(RDS SLA は Micro クラス起因の停止を除外・Cloud SQL は共有コアが対象外)。見送り AlloyDB(最小固定費が過大)
DB 接続採用 プライベート IP 直結(Direct VPC egress)AWS 案(VPC 内 Lambda → RDS 直結)と同等のプライベート接続・公開面なし。差は外向き通信: AWS は NAT Gateway(~$47/月)が必須になるのに対し、GCP は private-ranges-only 設定で公衆向けトラフィックが VPC を経由しないため NAT 不要。プールは Prisma 標準(インスタンスが長命なため機能する)
オブジェクトストレージ採用 Cloud Storage(東京)AWS: S3 継続(移行不要)。LiveKit Egress は GCS 直書きもネイティブサポート。視聴は署名付き URL(V4)= presigned GET 同等。90 日で Coldline へライフサイクル移行(S3 Glacier IR 相当・現行運用を踏襲)。既存 S3 在庫(~8.7TB)は移行 or 残置を採否確定時に判断
W1〜W6 配信採用 Pub/Sub(push + dead-letter topic)AWS: SQS + DLQ + 配信 Lambda。リトライ・DLT 組み込みで同等。push → コアの配信ハンドラ(OIDC 検証)→ HMAC 署名して minedia-www へ
録画→文字起こし採用 Cloud WorkflowsAWS: Step Functions。ステップ実行・ステップ単位リトライは同等だが、redrive(失敗した実行の途中再開)と実行履歴の可視化は Step Functions が優位。Workflows は失敗実行の再実行が最初からになるため冪等設計が前提
定期実行採用 Cloud SchedulerAWS: EventBridge Scheduler と同等。OIDC 付き HTTP でコアのリコンサイルを起動(3 ジョブまで無料)
チャット変更なし LiveKit データチャネル再利用(サーバー権威型)不使用 独自 WS サーバー(Cloud Run は WS 可能だが持たない方針を維持)
ルーム SPA採用 Vite + React SPA + Firebase Hosting 配信AWS: CloudFront + S3(~$2〜5/月)。Firebase Hosting は無料枠内で、PR ごとのプレビューチャンネルを標準装備
入口ドメイン(api.* / admin.*採用 外部アプリケーション LB(マネージド証明書 + serverless NEG)独自ドメイン管理は必須要件。1 つの LB がホスト名ルーティングで api.* → ①・admin.* → ③ を振り分け(転送ルール共用・追加費用なし)。見送り Cloud Run ドメインマッピング(Preview)・Firebase rewrite(API が CDN 経由になる)
レート制限採用 Cloud Armor(LB 上のポリシー)AWS: API Gateway スロットリング(WAF は HTTP API 非対応・必要時は CloudFront 前段に付与)。Cloud Armor は LB 上のポリシーで ~$6/月(§4
管理画面(開発者向け)採用 Refine SPA を Cloud Run 配信 + IAP(LB バックエンドで有効化AWS: CloudFront + Lambda@Edge + Cognito を自作(実装 1〜2 日規模)。IAP はマネージドのゲートを設定するだけx-goog-iap-jwt-assertion 検証)。admin.* を LB でホストするため IAP は LB のバックエンドサービス側で有効化(Cloud Run 直接統合との二重設定は不可)。あわせて管理画面 Cloud Run の ingress を LB 経由のみに制限し、素の run.app URL の抜け道を遮断する
メディア外部 LiveKit Cloud(SFU + Egress・Ship プラン変更なし。Egress の書き込み先のみ S3 → GCS
AI モデレーター外部 LiveKit Managed Agent Hosting変更なし
文字起こし AI外部 Azure Speech / OpenAI Whisper / ElevenLabs変更なし。将来 Google STT(東京)へ寄せて国内完結にする選択肢が生まれる
オブザーバビリティCloud Logging / Cloud Trace(標準 OTel SDK)+ @sentry/nodeTeam プランAWS: CloudWatch Logs + X-Ray(~$3〜5/月)。両案とも標準 OTel SDK が使えて同等。Cloud Logging は 50GiB/月の無料枠内で $0
minedia-www既存 現行インフラのまま(Rails)変更なし。REST(ApiKey)呼び出し・W1〜W6 受信の契約はクラウド選定と独立で、AWS 案とも完全同一

2. 全体構成図

クリックで拡大 🔍
全体構成図(Google Cloud 案・静的構造): ブラウザ(全ロール)はルーム SPA へ HTTPS(静的アセット・CDN)、外部 ALB(api.*・マネージド証明書・Cloud Armor)経由で基盤コア Cloud Run へ HTTPS(REST)、LiveKit Cloud へ WebRTC / WSS で接続。Google Cloud ゾーンには基盤コア(Cloud Run・Hono + zod-openapi + Prisma 7・東京・min-instances=1)、Pub/Sub(W1〜W6 + dead-letter topic)、Cloud Scheduler、Cloud Workflows、管理画面(Refine SPA・Cloud Run 配信 + IAP)が並び、asia-northeast1(東京)サブゾーンに Cloud Storage と Cloud SQL for PostgreSQL(db-g1-small・プライベート IP)。基盤コアから Pub/Sub / Scheduler / Workflows へは HTTPS(サービス間認証・OIDC)、Cloud SQL へは PostgreSQL(プライベート IP・VPC 内)。管理画面から基盤コアへ HTTPS(IAM ID トークン・run.invoker)。基盤コアと LiveKit Cloud は HTTPS(Server API / Webhook)で相互接続。LiveKit Cloud から Cloud Storage へ HTTPS(GCS API・直書き)。minedia-www(Rails・既存)は基盤コアへ HTTPS(REST・ApiKey)で接続し、Webhook(HMAC 署名)を受信、Cloud Storage へ HTTPS(署名付き GET)。Google Cloud から Sentry へ HTTPS(エラーイベント)

主要フロー

  1. 入室: ブラウザ → SPA → api.*(LB・Cloud Armor)→ 基盤コア(参加 JWT 検証 → RoomPolicy → LiveKit トークン発行)→ LiveKit へメディア直結。映像・音声は Google Cloud を通らない(AWS 案と同一構造)
  2. チャット/ルームイベント(サーバー権威型): 送信=ブラウザ → api.*(LB)→ コアの HTTP ingest(RoomPolicy 認可 → Cloud SQL 永続化 → 宛先算出)→ RoomServiceClient.sendData → LiveKit データチャネルで配信。設計は AWS 案と完全同一(実装はコンテナ上の Node で動くだけ)
  3. 録画: LiveKit Egress → GCS 東京へ直書き → webhook → Cloud Workflows が文字起こしをステップ実行 → W6 配信
  4. W1〜W6: 基盤コア → Pub/Sub publish → push サブスクリプション(OIDC)→ コアの配信ハンドラ → HMAC 署名 Webhook → minedia-www。リトライ超過は dead-letter topic へ退避
  5. DB: 基盤コア → VPC 内プライベート IP → Cloud SQL。同一リージョン内で RTT 最小(AWS 案の VPC 内 Lambda → RDS と同型)
  6. 録画視聴: download-url API で署名付き URL(V4)を発行し GCS から直接配信

3. 技術スタック

3-1. サービス構成(デプロイ単位)

サービスは「デプロイとアクセス制御の境界」で切る。AWS 案が API / SQS / Cron / SFn を個別の Lambda 関数に分割するのに対し、Cloud Run は複数の役割(API / queue push 受け / cron 受け / workflows コールバック)を同一サービスの HTTP エンドポイントとして同居できるため、基盤コアの非同期処理は分割しない。

サービス中身分割理由
① 基盤コアapps/coreCloud Run サービス: Hono(REST)+ /internal/queue(Pub/Sub push)+ /internal/cron(Scheduler)+ Workflows コールバック + /internal/adminAPI 契約と非同期処理が同じ Prisma スキーマ・RoomPolicy を共有。min-instances=1 はこのサービスのみ
② ルーム SPAapps/interview-roomFirebase Hosting(静的配信)UI は API と独立したデプロイ頻度。配信は CDN エッジ最寄り(AWS 案の CloudFront + S3 相当)
③ 管理画面apps/adminCloud Run サービス(静的配信 + プロキシ)+ IAPIAP を被せる境界を公開物と分離(AWS 案では Lambda@Edge + Cognito を自作する箇所)

ドメインは入口単位に割り当てる。

ドメイン入口ルーティング先備考
api.*外部 LB(マネージド証明書 + Cloud Armor)serverless NEG → ① 基盤コアminedia-www の REST もここを叩く。呼び出し側は api.* しか知らないため、裏の実体を将来差し替えても無変更で済む
admin.*同じ LB(ホスト名ルーティング)serverless NEG → ③ 管理画面IAP はこのバックエンドのみ有効化api.* 側には付けない)
room.*Firebase Hosting(カスタムドメイン機能)② ルーム SPALB 不要・CDN 配信
  • 裏口の遮断: ①③とも ingress を「内部 + Cloud Load Balancing」に制限し、素の run.app URL からの直接アクセス(IAP / Cloud Armor の迂回)を塞ぐ
  • 将来の分離: 負荷特性が分かれたら、queue / workflows の受け口を④の Cloud Run サービスとして分離できる(同一イメージを別サービス名でデプロイするだけ)
🔗

サービス間認証(Service Bindings 相当): Cloud Run のサービス間呼び出しは IAM で閉じる。

  • 呼び出し側のサービスアカウントに roles/run.invoker を付与し、ID トークン(OIDC)付きで HTTPS 呼び出し
  • コア側は /internal/* を IAM 認証必須にし、公開インターネットに管理 API の入口を持たない
  • 管理画面は「ブラウザ → 管理画面 Cloud Run(自オリジン)→ サーバー側プロキシが ID トークンを付与 → コアの /internal/admin」の経路。CORS 不要・ApiKey 非露出(AWS 案と共通の方針)
apps/core/                     ← 基盤コア(Cloud Run)
  Dockerfile                   ← リポジトリルートをビルドコンテキストに(pnpm workspace 対応)
  src/index.ts                 ← @hono/node-server($PORT / 0.0.0.0 で listen)
  src/api/                     ← Hono(@hono/zod-openapi ルート定義・ミドルウェア)
  src/queue/ src/workflows/ src/cron/ src/lib/
  prisma/schema.prisma
apps/interview-room/                 ← ルーム SPA(Firebase Hosting)
apps/admin/                    ← 管理画面(Refine・Cloud Run + IAP)
packages/contracts/            ← zod スキーマ・生成 openapi.yaml・API 型(全アプリで共有)
terraform/                     ← VPC / Cloud SQL / Pub/Sub / Workflows / IAM(使用サービスを固定)

3-2. 基盤コア(apps/core)

Node 標準ランタイムのため、ライブラリ選定は AWS 案(Lambda)とほぼ共通。差分はストレージクライアントと「HTTP サーバーをそのまま動かせるか」のみ。

領域採用AWS 案との差・備考
ランタイムNode 22 + @hono/node-server$PORT(既定 8080)・0.0.0.0 で listen(Cloud Run 必須要件)。AWS 案の hono/aws-lambda アダプタは不要=ローカルと本番が同一のコンテナ・同一のサーバープロセス
HTTP / 契約hono + @hono/zod-openapi変更なし ルート定義=zod=OpenAPI の単一ソース(G1 の実体)
OpenAPI UI@scalar/hono-api-reference変更なし /docs に Scalar UI をマウント
ORMprisma 7 + @prisma/adapter-pgインスタンスが長命なため Prisma 標準プールが機能(プールサイズ × 最大インスタンス数を Cloud SQL max_connections 内に設計。AWS 案の「予約同時実行数 + RDS Proxy 後付け」に相当する制御)。prisma migrate は Cloud Run Job で実行(VPC 内から到達)
JWTjose変更なし EdDSA 署名・/.well-known/jwks.json 公開
LiveKitlivekit-server-sdkNode ネイティブ環境で素直に動作(AWS 案と同等)
GCS@google-cloud/storage署名付き URL(V4)の発行 / put。AWS 案の @aws-sdk/client-s3 + s3-request-presigner に対応
ApiKey 照合bcrypt + crypto.timingSafeEqualネイティブ実装が使える(AWS 案と同等)
バリデーションzodpackages/contracts で共有)変更なし
ログ / 監視構造化 console(JSON → Cloud Logging 自動収集)、標準 OTel SDK → Cloud Trace@sentry/nodetracesSampleRate: 0AWS 案(CloudWatch + X-Ray)と同等の構図。集計イベントはログベース指標または BigQuery ログシンクで実装
テストvitest(素の Node pool)、convention test本番との環境差はコンテナの同一性で吸収(AWS 案は SAM ローカル等でエミュレート)

3-3. ルーム SPA(apps/interview-room)

ライブラリ構成は AWS 案と共通(livekit-client / @livekit/components-react / ConnectionCheck / openapi-fetch / @tanstack/react-query + zustand / Tailwind CSS / @sentry/react)。差は配信のみ: CloudFront + S3 → Firebase Hosting(プレビューチャンネルで PR ごとの確認 URL を自動発行)。

3-4. 管理画面(apps/admin)

Refine(React)+ Vite を Cloud Run で静的配信し、admin.*(LB)でホストする。API クライアントは SPA と同じ openapi-fetch を共有。

  • ゲート: IAP を LB のバックエンドサービスで有効化。Google アカウント / グループ単位の Zero Trust ゲートで、利用者を Google アカウントで統制できることが前提(組織外ユーザーを許可する場合は OAuth クライアント設定が必要・§5
  • データ取得: 基盤コアの内部プロキシ /internal/admin 経由。コア側で x-goog-iap-jwt-assertion を検証し、テナント ApiKey は露出しない
  • JWT 検証: 直接統合と同一構図。aud の期待値がバックエンドサービス ID 形式になる点のみ異なる
  • 適用範囲: IAP を付けるのは管理画面のバックエンドのみ(api.* 側や、Pub/Sub push 等の OIDC 経路を持つコア①には付けない)。ingress 制限による run.app 裏口の遮断とセットで成立する§3-1

3-5. 開発ツールチェーン

領域採用
モノレポpnpm workspace(apps 3つ + packages/contracts変更なし
デプロイgcloud run deploy(Artifact Registry + Cloud Build)/ firebase deploy --only hosting。ロールバックは Cloud Run revision 切替・Hosting バージョン戻し
秘密情報Secret Manager(--set-secrets で環境変数注入)。AWS Secrets Manager 連携が不要になり 1 社に集約
環境分離dev / stg / prd を GCP プロジェクト分離(AWS 案のアカウント / スタック分離に相当。IAM・Secret・課金も自然に分離)
CI/CDGitHub Actions + Workload Identity Federation(キーレス): typecheck / lint / test → prisma migrate(Cloud Run Job)→ deploy
IaCTerraform(VPC・Cloud SQL・Pub/Sub・Workflows・IAM)。使用サービスを本ページの構成に固定し増やさない(運用対象最小の規律)
OpenAPI生成 yaml を redocly lint、UI 配信は Scalar、@stoplight/prism-cli モック 変更なし
LintESLint(no-floating-promises 必須)+ Prettier 変更なし

3-6. minedia-www 側(レーンB・Phase 5)

変更なし AWS 案と完全同一(faraday + faraday-retry / committee 契約テスト / OpenSSL::HMAC 署名検証・イベント id dedup)。minedia-www から見える契約(REST・ApiKey・W1〜W6)はクラウド選定と独立している。

4. 月額コスト試算

規模前提(Medium): AWS 案と同一(月200インタビュー×60分・全件録画60分・AI モデレーター比率 30%・¥160/USD)。LiveKit 費は #5317 の既存試算を使用。オーダー把握用の概算であり、規模実値の確定後に精緻化する。ストレージのみ規模前提ではなく現行 S3 の実測値を使用(在庫 ~8.7TB・削除なし=90日で低頻度クラス移行・視聴転送 月0〜211GB のバースト型。GCS の対応クラスに単価換算)。

4-1. ホスティング層(クラウド請求額)

項目月額算定前提
Cloud Run(基盤コア)~$10min-instances=1(1 vCPU / 512MiB 常時ウォーム・アイドル単価 $0.0000025/vCPU 秒・リクエストベース課金)。リクエスト実勢 月5〜10万件は無料枠(200万 req)内。インスタンスベース課金だと ~$50 になるため課金モデル選択に注意
Cloud Run(管理画面)~$0ゼロスケール(社内利用のみ・コールドスタート許容)
Firebase Hosting(ルーム SPA)$0無料枠(保管 10GB・転送 360MB/日)内
Cloud SQL for PostgreSQL~$45db-g1-small(共有 1vCPU / 1.7GB・東京)$0.046/h ≈ $33.58 + SSD 50GB×$0.221 ≈ $11.05。db-f1-micro なら ~$21。共有コアは SLA 対象外
Pub/Sub / Workflows / Scheduler~$0W1〜W6 は月数千メッセージ・Workflows 月数百実行=無料枠内。Scheduler は 3 ジョブまで無料
IAP / Secret Manager / Artifact Registry / Direct VPC egress~$0IAP は無料。Secret Manager・Artifact Registry はこの規模では誤差
Cloud Logging / Cloud Trace$0~22万イベント/月 ≪ 無料枠(ログ 50GiB/月)
外部 ALB(api.* / admin.* 終端)~$18グローバル外部 ALB の転送ルール 1 本 $0.025/h × 730h ≈ $18(両ホスト名で共用。リージョナル ALB だと $0.038/h ≈ $28)。マネージド証明書は追加費用なし。データ処理課金($0.012/GiB 送受)は API トラフィック(メディア非経由)ではこの規模で誤差
Cloud Armor(レート制限)~$61 ポリシー($5)+ ルール数本($1/本)。リクエスト課金はこの規模では誤差
Google Cloud 小計~$80
GCS 保管~$54実測: 在庫 ~8.7TB=Coldline 8.6TB×$0.006 + Standard 0.1TB×$0.023(90日で Coldline 移行・削除なし=累積型。S3 実測 ~$45 の GCS 換算。Coldline は Glacier IR 比で単価 +$0.001/GB)
GCS 視聴転送~$6実測: 直近6ヶ月平均(月 0〜211GB×$0.12/GB・ピーク月 ~$25。月次変動大のバースト型)。Coldline 取り出し $0.02/GB はこの流量では誤差
ホスティング計~$140

4-2. 監視

項目月額備考
Sentry~$26Team プラン 変更なし。traces / logs は Cloud Logging / Trace で完結し、外部集約先(Grafana Cloud 等)は導入しない
~$26

4-3. 外部 SaaS(クラウド選定と独立・参考)

項目月額備考
LiveKit Cloud(Ship・録画込)~$507(≈¥81,200)変更なし 基本 $50 + 下り転送 ≈ $229 + 合成録画 ≈ $228(#5317 試算)。Egress の書き込み先が GCS になるだけで料金は不変
AI(OpenAI Realtime 30% + STT)未定現行の実利用量を調査後に反映
~$507 + AI(未定)

4-4. 総計・感度

月額
ホスティング + 監視~$165
外部 SaaS 込み総計(確定分)~$670 + AI(未定)
📉

感度: ストレージは設計当初の想定(180日削除・定常在庫 ~1.2TB・視聴転送 ~400GB/月)と実測が大きく乖離しており(削除なし運用の累積在庫 ~8.7TB・視聴はバースト型で月平均 ~50GB)、本試算は実測側を採用している。録画保持ポリシー次第で保管費は変わる。総額の支配項は LiveKit(~$507)。残る感度は規模実値と AI 実測。AWS 案とのコスト比較・採否評価は採否判断資料として別管理。

5. 未決事項(採否判断・Phase 0 で確定)

#事項対応
1コールドスタート実測min-instances なし / ありで入室 API のレイテンシを実測し、要否とコストを確定
2社内 ID 基盤の確認管理画面利用者を Google アカウント(グループ)で統制できるか確認。組織外ユーザーを許可する場合は OAuth クライアント設定が必要

6. 経緯資料

  • インフラ構成(AWS 案)比較対象。評価軸・規模前提・ストレージ実測・minedia-www 側契約を共有する
  • インフラ構成 — Cloudflare 軸(不採用決定)。本設計の原型であり、アプリ構成(Hono + Prisma + zod + jose)と契約はここから継承
  • オブザーバビリティ — 監視設計。GCP 案では標準 OTel + Cloud Logging / Trace で実装する(設計自体は流用可能)

本ページは実査機能 新基盤のインフラ構成の Google Cloud 案です。構成図・評価・コスト試算・未決事項を AWS 統一案と同じ粒度で整理しています。