Open7

【GoogleCloud/GCP】Docker Container化したアプリをGoogle Cloud/GCPにDeployする📝

まさぴょん🐱まさぴょん🐱

Google Cloude (GCP)でDocker Container化したアプリをDeployする📝

FEは、Cloud Run / Cloud Storage + Cloud CDN / Firebase Hosting のいずれかで迷っていましたが、メンテのしやすさを考えて、Honoと同様に Cloud Run 構築としました📝

gcloud CLI (Google Cloud CLI)のインストールについて📝

https://zenn.dev/manase/scraps/3180db43960b0d

Cloud SQLの構築について📝

Hono の Deployについて📝

React/Vite の Deployについて📝

https://qiita.com/Senritsu420/items/77fa8860591f88bdcee2

https://zenn.dev/aagfsgss/articles/80f687aee76a72

https://github.com/GoogleCloudPlatform/community/blob/master/archived/deploy-react-nginx-cloud-run/index.md

https://qiita.com/kanedaq/items/6cd107837b1076292ffb

まさぴょん🐱まさぴょん🐱

o3 のおすすめ📝

まずは結論だけ — ほとんどのケースで “Hono API を Cloud Run、PostgreSQL を Cloud SQL、React/Vite の静的ファイルを Cloud Storage + Cloud CDN” という構成がもっとも手軽かつ運用コストが低い です。
Cloud Run は Docker イメージをそのまま実行でき、近年は マルチコンテナ(sidecar) も正式サポートされたため、必要ならフロントとバックエンドを 1 サービス内にまとめることも可能です。
(Google Cloud, Google Cloud)


1. デプロイの選択肢と比較

目的 推奨サービス 主なメリット 向いていないケース
簡単に HTTP コンテナをスケール Cloud Run リクエスト単位オートスケール、マルチコンテナ、Cloud Run→Cloud SQL 接続が公式サポート 常時接続が必要な WebSocket、大規模 Stateful 処理
Compose の複数サービスをそのままクラスター化 GKE Autopilot Kubernetes 機能をフル活用、Pod/ノード管理を Google にオフロード K8s の学習コストを割きたくない場合
既存 Node/React モノリスを VM と同じ感覚で App Engine Flexible VM 相当の自由度、buildpack/Cloud Build 統合 起動が Cloud Run より遅い、料金が高め

Postgres

  • Cloud SQL for PostgreSQL はバックアップ・パッチ適用・レプリカをマネージドで提供します (Google Cloud)
  • GKE に自己ホストする手もありますが、OS パッチやフェイルオーバを自前で運用する必要があり、Cloud SQL と比べると運用負荷が高くなります。(netapp.com)

2. 推奨アーキテクチャ

2-A. 静的フロントエンドを Cloud Storage + Cloud CDN に置く

  1. vite build で生成された dist/ をバケットへアップロード
  2. バケットを バックエンド・バケット として HTTPS 負荷分散器に接続
  3. Cloud CDN を有効化して高速配信とキャッシュを確保 (Medium, Stack Overflow)
  4. API 呼び出しは /api/* を Cloud Run にルーティング

メリット: Node ランタイム不要でゼロ運用。エッジキャッシュで高速。
注意点: CSR ルーティングのため /* → index.html マッピングを設定。

2-B. Cloud Run マルチコンテナにまとめる場合

  • Docker-compose.yml の frontend と backend を 二つのコンテナ として同じ Cloud Run サービスに含める
  • gcloud run deploy--container フラグを複数書くだけで OK (Google Cloud)
  • ローカルホストで相互通信できるので CORS や LB 不要、レイテンシ削減 (Stack Overflow)

3. GKE Autopilot を選ぶ場合

  • Compose ファイルを Kompose で Kubernetes マニフェストに変換し、そのまま kubectl apply すればデプロイできます (Kompose, Kubernetes)
  • Autopilot は Pod のリソース要求に応じてノードを自動調整し、課金も request 量ベース なので学習コスト以外の負担が小さい (Google Cloud, Stack Overflow)
  • StatefulSet やカスタムサイドカー、複雑なネットワークが必要なときに有利 (Google Cloud)

4. App Engine Flexible

  • Dockerfile をそのまま使え、VM 相当の自由度を保ちつつオートスケールします (Google Cloud)
  • 週次再起動やデプロイ時間が Cloud Run より長い点に注意が必要です。開発初期からコンテナを完全に制御したい場合のみ検討してください。(Medium)

5. CI/CD パイプライン

  1. Cloud Build のトリガーで push→ビルドを自動化し、Artifact Registry へ push (Google Cloud)
  2. 成功したら gcloud run deploy または Cloud Deploy で段階的リリース(test→stg→prod) (Google Cloud, Stack Overflow)
  3. Cloud Run は Artifact Registry から直接イメージを pull できます (Google Cloud, Medium)

6. コスト・スケールの目安

サービス 無負荷時 リクエスト急増時 初期学習コスト
Cloud Run 0 円〜(常時ゼロスケール可) 1000 req/s 超でも自動スケール
GKE Autopilot Pod request 量に比例 水平・垂直とも自動
App Engine Flex 常時起動 VM × インスタンス分課金 インスタンス単位水平スケール

7. 今後のステップ

  1. PoC: Cloud Run に Hono API を単一コンテナでデプロイ → Cloud SQL Proxy アドオンで DB 接続確認
  2. フロント: Vite build を Cloud Storage へ配置し CDN 化、もしくはマルチコンテナ化を比較
  3. CI/CD: GitHub または GitLab → Cloud Build → Cloud Deploy → Cloud Run のパイプラインを実装
  4. 監視: Cloud Monitoring/Logging を有効化し、アラートポリシーを設定

この構成なら段階的に GKE へスケールアップするルートも残しつつ、まずは Cloud Run/Cloud SQL で最小限の運用負荷で本番公開が可能です。

まさぴょん🐱まさぴょん🐱

Google Cloud上でHonoのアプリを デプロイする場合には どんなサービスを使うのがいいか?

結論 ― まずは Cloud Run(フル マネージド)を使うのが鉄板

Hono は「Fetch API で書ける軽量アプリをどこでも動かす」ことを目指したフレームワークです。公式ドキュメントでも Google Cloud Run でのデプロイを最初に紹介 しており、Docker/Buildpack どちらでも簡単に動きます(Hono)。
Cloud Run は

  • コンテナさえ用意すればランタイムを選ばず動く(Node 22 / Deno / Bun など)
  • リクエスト単位で自動スケールし、ゼロにも戻る
  • min instances を 1 台置くだけでコールドスタート ≒ 2 秒問題をほぼ解消
  • WebSocket・HTTP/2・gRPC ストリームが GA 済みなので Hono の ws() もそのまま動く(Google Cloud)

という理由で、Hono の「軽い API を素早く出したい」という要件と最も相性が良いです。


Cloud Run での基本的な流れ

  1. Dockerfile か Buildpack を選ぶ
    Hono の例に合わせるなら Buildpack が楽:gcloud run deploy <SERVICE> --source . だけで OK。ポートは 8080 に合わせます(Hono, Google Cloud)

  2. リージョンと実行環境を決める

    • 低レイテンシなら asia-northeast1(東京)
    • 常時待機なら --min-instances=1 を指定
  3. CI/CD を Cloud Build に繋ぐ
    GitHub/GitLab への push トリガで自動ビルド → Cloud Run へデプロイ

  4. Cloud SQL(PostgreSQL) と繋ぐ場合
    Cloud SQL Auth Proxy を sidecar にするか、VPC コネクタ経由で接続

Dockerfile 最小例(Node 22)

FROM node:22-slim
WORKDIR /app
COPY package*.json .
RUN npm ci --omit=dev
COPY . .
ENV PORT=8080
CMD ["node", "dist/index.js"]

代替オプションと選定指針

シナリオ 推奨サービス コメント
「1 つの HTTP 関数だけ。イベント駆動も欲しい」 Cloud Run functions(旧 Cloud Functions 2nd gen) Node 22 が GA 済み。Cloud Run の技術基盤なので遅延もほぼ同じ。デプロイは gcloud functions deploy 一発(Google Cloud)
「常時オンライン・VM レベルの自由度が欲しい」 App Engine Standard/Flexible push-to-deploy が楽。ただしランタイムや同時接続に制限あり
「マイクロサービスを束ねたい / サイドカー多数」 GKE Autopilot Kubernetes ネイティブ。Hono も Ingress 配下で OK
「OS から自由に触りたい、長い WebSocket を大量に張る」 Compute Engine ただし手動運用コストが増える

Cloud Run で Hono を動かすときの Tips

  • Concurrency: デフォルト 80。小さな API なら上げても OK。WebSocket は 1 接続 = 1 リクエストなので下げ目に。
  • CPU 割当: --cpu=1 --memory=512Mi くらいが Node アプリの標準的なスタート地点。
  • シークレット管理: Cloud Secret Manager → 環境変数にバインド。
  • 監視: Cloud Logging + Cloud Trace → /metrics を Prometheus で刈り取る構成が楽。
  • ステージング環境: gcloud run deploy <SERVICE>-stg --region=asia-northeast1 --allow-unauthenticated --traffic=0 で Revision 単位の Blue-Green が簡単。

まとめ

  • まずは Cloud Run — コンテナをそのまま持ち込み、自動スケールと最新ランタイムを享受
  • 小規模 FaaS ライク → Cloud Run functions(Cloud Functions 2nd gen)
  • 常時稼働やフルカスタム要件が強ければ App Engine / GKE / Compute Engine を検討

Hono 公式の手順どおりに gcloud run deploy すれば数分で公開できます。試してみてください!

まさぴょん🐱まさぴょん🐱

Google CloudでPostgreSQLのDBを使う場合は どうするのがいいですか?

Google Cloud 上で PostgreSQL を使う主な選択肢

方式 特長 運用負荷 典型ユースケース
Cloud SQL for PostgreSQL フルマネージド。自動バックアップ・パッチ・フェイルオーバー。Standard/Enterprise Plus エディションあり 一般的な Web/業務アプリ。数百 GB 〜 数 TB 規模の OLTP
AlloyDB for PostgreSQL 100 % PostgreSQL 互換+Google 独自エンジン。最大 4 × OLTP・100 × 分析性能、ベクトル検索も高速 高スループット OLTP、HTAP、AI/分析ワークロード (cloudbabble.co.uk, Medium)
自前コンテナ(GKE/Compute Engine 等) バージョンや OS 完全自由 特殊拡張の利用、ライセンス要件、オンプレ ⇒ GCP リフト&シフト段階

結論(迷ったら)
まずは Cloud SQL が王道です。後から AlloyDB へスムーズに移行できる公式パス(Cloud SQL → AlloyDB へのバックアップ取り込み)が 2025 年 5 月に GA (Google Cloud) になったため、将来のスケールアップにも備えられます。


Cloud SQL を採用する場合の実装ガイド

1. インスタンス作成

  1. バージョンを合わせる – ローカル Docker の PostgreSQL と同じメジャー/マイナーを指定
  2. リージョン & ゾーン冗長 (High Availability) を有効化
  3. ディスク自動拡張・自動バックアップをオン

2. 接続方式

接続元 推奨 備考
Cloud Run/Hono サーバー Cloud SQL Auth Proxy ソケット or Cloud SQL Connector Cloud Run 用ガイド (Google Cloud)
ローカル開発 Cloud SQL Auth Proxy Docker イメージ docker-compose.yml に proxy サービスを追加するとポート番号だけで開発環境が共通化 (Google Cloud)
DB クライアント (DBeaver 等) Cloud SQL Auth Proxy 経由 or SSL 直結 Authorized Networks を使わず IAM/Bearer 認証に統一可

<details>
<summary>Node(pg)接続例</summary>

import { Pool } from 'pg';

const pool = new Pool({
  host: process.env.DB_HOST ?? '/cloudsql/' + process.env.INSTANCE_CONNECTION_NAME, // Unix socket
  database: process.env.DB_NAME,
  user: process.env.DB_USER,
  password: process.env.DB_PASS,
  max: 10,          // Cloud SQL は接続数に制限があるため小さめ + pgbouncer 推奨
  idleTimeoutMillis: 30000,
});
export const query = (text: string, params?: any[]) => pool.query(text, params);

</details>

3. マイグレーション

  • 開発 DB → Cloud SQL

    • pg_dump | psql で即時コピー
    • もしくは Database Migration Service (DMS) を使うと継続レプリケーションも可。2025 年には SQL Server → PostgreSQL / AlloyDB も AI 変換付きでサポート (Google Cloud)。

4. 運用ベストプラクティス

  • 自動 VACUUM の確認、メモリ・CPU のライトサイジング
  • Committed Use Discounts や停止時間を利用したコスト最適化 (sedai.io)
  • pgbouncer / Cloud SQL 接続プールを併用し、Cloud Run の autoscale に備える
  • メンテナンスウィンドウ はトラフィックの少ない時間帯に設定

AlloyDB を選ぶ基準

判断ポイント 目安
同時接続数・QPS が Cloud SQL 上限付近(数万 QPS 超)
大量の JSONB or ベクトル検索 (AI Embeddings)
OLTP と集計/ダッシュボード (HTAP) を 1 台でこなしたい
価格を抑えつつ標準的な OLTP を安定稼働させたい Cloud SQL が無難

AlloyDB は クラスタ単位課金(最小 2 vCPU + 16 GB RAM)で Cloud SQL より高めですが、ベクトル最適化や列指向キャッシュで “性能あたりコスト” が良い場合もあります (Bytebase)。


自前コンテナで運用する場合

  • Compute Engine か GKE で Docker コンテナをそのまま起動
  • 自分で バックアップ、パッチ適用、監視、レプリケーション、フェイルオーバーを実装
  • 本番で高可用性を担保するには Patroni + HAProxy などを組む必要があり、運用コストが大きい
  • Cloud SQL の料金と人的コストを比較すると、多くのケースで Cloud SQL が安価

ローカル ⇄ 本番の環境差分を小さくするコツ

  1. .env に接続文字列を抽象化

    • DATABASE_URL=postgresql:///app (ローカル)
    • DATABASE_URL=unix:/cloudsql/<INSTANCE>?user=app&password=... (Cloud Run)
  2. docker-compose.override.yml で Cloud SQL Auth Proxy を追加し、開発中でも本番 DB へ統合テスト可能

  3. Prisma/TypeORM Migrate を使ってスキーマをコード化し、本番適用を CI/CD(Cloud Build)上で自動化


まとめ

  • まず Cloud SQL。運用を Google に任せつつ、Cloud Run との親和性が高い。
  • パフォーマンスが頭打ちになったら AlloyDB へワン - クリック移行が 2025 年から GA。
  • 特殊要件がない限り、自前コンテナ運用は避ける ほうがトータルコストは下がります。

これで Google Cloud 上の PostgreSQL 選定から導入、ローカルとの統合まで一通り押さえられます。ご不明点や具体的な Terraform / IaC 例が必要であればお知らせください!

まさぴょん🐱まさぴょん🐱

Google Cloud上で ReactとViteのフロントエンドアプリを デプロイするにはどんなサービスを使うのがいいですか?

以下の3パターンが、Google Cloud で React + Vite でビルドしたフロントエンドをデプロイするときによく使われる選択肢です。要件に合わせて使い分けるのがポイントです。


1. 最も手軽:Firebase Hosting(推奨)

特徴 内容
ビルド成果物 vite build で作られる静的ファイル一式
配信 Google のグローバル CDN。HTTP/2・自動 TLS
CI/CD firebase init hosting ➜ GitHub Action 連携で PR ごとにプレビュー環境生成可
動的処理 必要に応じて Cloud Functions / Cloud Run を“同じドメイン”にリライト可能
コスト 小規模ならほぼ無料(配信量/書き込み量で課金)
npm run build                       # vite build
npm i -g firebase-tools
firebase login
firebase init hosting               # public ディレクトリに dist を指定
firebase deploy --only hosting

SPA なら "rewrites": [{ "source": "**", "destination": "/index.html" }]firebase.json に追加すると、F5 更新でも 404 が起きません。(Firebase)


2. 純 GCP だけで完結:Cloud Storage + Cloud CDN

特徴 内容
ビルド成果物 静的ファイルをバケットにアップロード
配信 Cloud CDN を有効化した Load Balancer 経由で高速配信
カスタムドメイン LB で TLS 証明書を終端
CI/CD Cloud Build や GitHub Actions で gsutil rsync するだけ
コスト バケット保管料 + CDN 転送量。非常に低コスト
# バケット作成(東京リージョン例)
gsutil mb -p ${PROJECT_ID} -l asia-northeast1 gs://example-spa
# SPA 用に index.html を既定ドキュメントに
gsutil web set -m index.html -e 404.html gs://example-spa
# アップロード
gsutil rsync -R ./dist gs://example-spa

HTTPS/カスタムドメインは「外部 HTTP(S) Load Balancer → Cloud CDN → Cloud Storage」に設定します。(Google Cloud, Google Cloud)


3. バックエンドと統合:Cloud Run(コンテナ)

特徴 内容
ビルド成果物 Dockerfile(Nginx などで /usr/share/nginx/html にコピー)
配信 コンテナ経由。必要なら Server-Side Rendering も同じサービスで実装可
高度な要求 A/B テスト用のヘッダ処理、認証付き配信、ゼロダウンタイム Blue/Green など
コスト リクエスト数/実行時間課金(アイドル時は 0 円)
# 例: 静的ファイルを Nginx で配信
FROM node:22-bookworm AS build
WORKDIR /app
COPY . .
RUN npm ci && npm run build

FROM nginx:1.27-alpine
COPY --from=build /app/dist /usr/share/nginx/html
EXPOSE 8080
CMD ["nginx", "-g", "daemon off;"]
gcloud run deploy vite-frontend \
  --source . \
  --platform managed \
  --region asia-northeast1 \
  --allow-unauthenticated

Cloud Run のスケールアウト/ゼロスケールやカナリアリリース機能を活用したい場合に便利です。フロントもバックエンド (Hono/TypeScript) も同じ Cloud Run ネームスペースで運用すれば、IAM や Secret Manager の統制が一元化できます。(Google Codelabs, Google Cloud)


どう選ぶ?

こんなとき ベストな選択肢
静的 SPA を“とにかく簡単”に公開したい Firebase Hosting
Firebase を使わず純 GCP だけで済ませたい/極小コストにしたい Cloud Storage + Cloud CDN
API も含め Cloud Run に統一、SSR や高度なルーティングをしたい Cloud Run

個人的おすすめ:学習・小規模運用なら Firebase Hosting。既に Compose でバックエンドをコンテナ化しており、Cloud Run で API を走らせる予定なら、フロント用に軽量 Nginx コンテナを用意し Cloud Run にデプロイすると運用が一本化できます。

それぞれ無料枠があるので、まずは Firebase Hosting か Cloud Storage で試して転送量・機能要件を見極め、必要に応じて Cloud Run にスケールアップ/統合する流れが失敗が少ないです。

まさぴょん🐱まさぴょん🐱

React/Vite FrontEndをCloud RunでDeployする場合の詳細について📝

下記の例を 「完成形」として見ると、ほぼそのまま gcloud run deploy に掛けられます。
ポイントは ①ビルド段階と配信段階を分離するマルチステージビルド②Cloud Run が期待するポート 8080 で Nginx を待ち受ける③SPA 用のリライトとキャッシュポリシー の 3 点です。


1 Dockerfile(例)

# ---------- ① Build stage ----------
FROM node:20-bookworm-slim AS builder
WORKDIR /app

# 依存解決
COPY package.json pnpm-lock.yaml ./
RUN npm i -g pnpm && pnpm install --frozen-lockfile

# アプリ本体
COPY . .
RUN pnpm run build          # dist/ が生成される

# ---------- ② Run stage ----------
FROM nginx:1.27-alpine     # 軽量イメージ
ENV PORT=8080              # Cloud Run が設定する $PORT と合わせる
EXPOSE 8080

# Nginx 設定を差し替え
COPY nginx.conf /etc/nginx/conf.d/default.conf

# ビルド成果物を配置
COPY --from=builder /app/dist /usr/share/nginx/html

CMD ["nginx", "-g", "daemon off;"]

変更点

  • 開発用 pnpm run dev は削除し、代わりに Nginx で配信
  • Cloud Run 固定のポート 8080 を listen する
  • ローカル開発時の「ボリュームマッピング」は不要(CI/CD でコードをコピー)

2 nginx.conf(SPA + キャッシュ最適化)

server {
  listen 8080;
  server_name _;               # 任意

  # ルートをビルド成果物に
  root /usr/share/nginx/html;
  index index.html;

  # 2.1 ハッシュ付きアセットを長期キャッシュ
  location /assets/ {
    try_files $uri $uri/ =404;
    add_header Cache-Control "public, max-age=31536000, immutable";
  }

  # 2.2 画像など /static/ 配下に置く場合(ビルド外の共有ディレクトリがあるとき)
  # location /static/ {
  #   alias /static/;  # 例: 別レイヤで COPY した場合
  #   add_header Cache-Control "public, max-age=86400";
  # }

  # 2.3 SPA ルーティング(存在しなければ index.html にフォールバック)
  location / {
    try_files $uri /index.html;
    add_header Cache-Control "no-cache";
  }

  # 2.4 gzip 圧縮(任意)
  gzip on;
  gzip_min_length 256;
  gzip_types text/css application/javascript application/json font/woff2;
}

✔️ この設定で出来ること

用途 設定内容
SPA ルーティング try_files $uri /index.html; で F5/直リンクでも 404 にならない
ビルド済みアセットの長期キャッシュ max-age=31536000, immutable で 1 年キャッシュ(ハッシュ付きファイルなので安全)
index.html の即時反映 no-cache を付けることでデプロイ直後の更新がブラウザに届く
画像など追加の静的ファイル ① Vite の /public 配下なら自動で dist/ 内に入る
② それ以外(ユーザーアップロード等)は Cloud Storage + CDN を推奨

3 静的ファイル(画像など)の扱い

3-1 ビルド時に含めるもの

  • src/assets/import logo from "./logo.png" … → assets/xxxxx.png にバンドル
  • public/images/hero.jpg … → 変更なしで dist/images/hero.jpg

どちらも そのまま Nginx が配信します。追加設定は不要です。

3-2 ランタイムで増えるファイル(ユーザーアップロード等)

Cloud Run は各インスタンスのファイルシステムが 揮発性 なので、次のいずれかが定番です。

シナリオ 推奨ストレージ
バケットで公開 URL が欲しい Cloud Storage(静的→Cloud CDN をアタッチ可)
アップロード → 変換 → CDN 配信 Cloud Storage + Cloud Functions / Cloud Run ジョブ
非公開ファイル/要認証ダウンロード Cloud Storage + Signed URL or Cloud IAM

アップロード後に返す URL をフロントで <img src="..."> に使えば Nginx への追加設定は不要です。


4 デプロイ例

gcloud run deploy vite-frontend \
  --source . \
  --platform managed \
  --region asia-northeast1 \
  --allow-unauthenticated
  • --source で Cloud Build が Dockerfile をビルドしてくれます(ローカルで docker build する場合はイメージ名指定で OK)。
  • カスタムドメイン/TLS は Cloud Run ドメインマッピング → Cloud DNS で CNAME 設定するだけです。

まとめ

  1. マルチステージ Dockerfile で Node ビルド → Nginx 配信へ切り替え
  2. nginx.conf に SPA 用フォールバックとキャッシュポリシーを追加
  3. ビルドに含まれる画像はそのまま配信、アップロード画像は Cloud Storage へ

この 3 点を押さえれば、React + Vite のフロントエンドは Cloud Run 上でも快適に動かせます。

まさぴょん🐱まさぴょん🐱

Cloud SQLでPostgreSQLを構築する場合の詳細📝

以下の手順どおりに Cloud SQL(PostgreSQL) へ接続できる Docker Compose 構成が作れます。
“やること” → “設定例” の順に並べたので、そのままコピーして試してみてください。


1. 事前準備(Cloud SQL 側)

手順 ポイント
① インスタンスを作成 PostgreSQL のバージョンをローカルと合わせる(例: 16)
② DB・ユーザー作成 appdb, appuser などロールを発行
③ サービスアカウント発行 Cloud SQL Client ロールを付与し、鍵(JSON) ダウンロード
④ INSTANCE_CONNECTION_NAME を控える 例: my-project:asia-northeast1:prod-db

2. ローカル用 Docker Compose 例

version: "3.9"
services:
  # Cloud SQL Auth Proxy (公式 v2 イメージ)
  cloudsql-proxy:
    image: gcr.io/cloud-sql-connectors/cloud-sql-proxy:2.16.0  # ←最新版を使う:contentReference[oaicite:0]{index=0}
    command:
      # TCP で 0.0.0.0:5432 を開ける
      - "--address=0.0.0.0"
      - "--port=5432"
      - "--credentials-file=/secrets/key.json"
      # Private IP を使う場合は --private-ip
      - "${INSTANCE_CONNECTION_NAME}"
    volumes:
      - ./secrets/key.json:/secrets/key.json:ro   # ③ で落とした鍵
    networks:
      - backend
    restart: unless-stopped

  # あなたの API(例: Hono / Node)
  api:
    build: ./server        # Dockerfile の場所
    env_file: .env         # DB 接続情報をここに
    depends_on:
      - cloudsql-proxy
    networks:
      - backend

networks:
  backend:

.env

# Cloud SQL の接続名
INSTANCE_CONNECTION_NAME=my-project:asia-northeast1:prod-db

# アプリ側が使う DB URL
# → cloudsql-proxy というホスト名は docker internal DNS で解決される
DATABASE_URL=postgresql://appuser:secret@cloudsql-proxy:5432/appdb

ポイント

  • 1 コンテナに 1 Auth Proxy を立てる必要はなく、Compose ネットワークを共有すれば何台でも同じ Proxy に繋げます。
  • 接続プール制限 (標準 Edition で ~500 接続) に注意。Prisma/pg なら pool_max=10 など小さめに。

3. 起動と動作確認

docker compose up -d          # 起動
docker compose logs -f cloudsql-proxy  # 成功すると “… ready for new connections” が出力
psql -h localhost -p 5432 -U appuser -d appdb  # 手元の psql で接続テスト

4. Cloud Run にデプロイするときの違い

ローカル (上記) Cloud Run
HOST=cloudsql-proxy /cloudsql/${INSTANCE_CONNECTION_NAME} という Unix ソケット を使う
Auth Proxy は自前コンテナ Cloud Run のサービス設定で “Cloud SQL 接続” を追加するだけで OK
DB URL 例:
postgresql://user:pass@cloudsql-proxy:5432/db
DB URL 例:
postgresql://user:pass@/cloudsql/my-proj:asia-northeast1:prod-db/db

5. バリエーション & TIPS

  • gcloud 認証を流用
    鍵を置きたくない場合は $HOME/.config/gcloud をマウントし --credentials-file を外せば、
    gcloud auth application-default login のトークンで動作します(Gist)。
  • Unix ソケットで開ける
    macOS/Linux なら --unix-socket /cloudsql を指定し、/cloudsql をボリューム共有すると
    TCP を開けずに済む(より安全)(Google Cloud)。
  • Private IP に統一
    VPC Peering で private IP を有効にした場合、Auth Proxy 起動オプションに --private-ip を追加すると
    公開 IP を一切使わず通信できます。

まとめ

  1. Auth Proxy を docker-compose に 1 コンテナ追加するだけ
  2. アプリ側の HOSTcloudsql-proxy(ポート 5432)に変える
  3. Cloud Run に上げるときは Unix ソケットに置き換えるだけ

これでローカル/本番のコード差分は環境変数だけに抑えられます。
Terraform や Cloud Build での自動デプロイ例も必要なら教えてください!