サーバーサイド処理が必要なアプリをCloud Runで本番運用できるようになる
この講座は中〜上級者向けのオプション講座です。Vercel で十分な場合はこの講座は不要です。まず講座06 Phase 6「Vercel では対応できないケース」を確認してから、必要と判断した場合に取り組んでください。
Docker・gcloud CLI・サーバーサイド処理など、初学者には難易度が高いトピックを扱います。
- Docker でアプリをコンテナ化し、本番環境に対応したイメージを作成できる
- Google Artifact Registry に Docker イメージを push できる
- Google Cloud Run にアプリをデプロイして HTTPS URL でアクセスできる
- Secret Manager で API キーをサーバーサイドで安全に管理できる
- コスト最適化されたスケーリング設定で運用できる
- コード修正から本番反映までのデプロイフローを確立できる
Phase 0: Vercel と Cloud Run の使い分け判断
STEP 0-1: 自分のケースが Cloud Run を必要とするか確認する
まず自分のケースが Cloud Run を必要とするかを確認しましょう。上記に1つも当てはまらない場合は Vercel で十分です。
| 要件 | Vercel | Cloud Run |
|---|---|---|
| 静的サイト・SPA(React/Vite) | ✅ 最適 | 可能だが過剰 |
| サーバーレス関数(短時間処理) | ✅ 最適 | 可能 |
| 常時起動の API サーバー | ❌ 不向き | ✅ 最適 |
| API キーをサーバーで完全秘匿 | △ 限定的 | ✅ 最適 |
| Docker コンテナのデプロイ | ❌ 非対応 | ✅ 最適 |
| Node.js Express / FastAPI | △ 制限あり | ✅ 最適 |
| 費用(低トラフィック時) | ✅ 無料 | ✅ ほぼ無料 |
| 設定の難易度 | ✅ 簡単 | ⚠️ 中〜上級 |
- バックエンド API サーバー(Express.js, FastAPI など)を本番で動かしたい
- API キーをフロントエンドのコードに一切含めたくない
- Dockerfile や Docker イメージを使いたい
- 既存の Docker コンテナを本番にデプロイしたい
ユーザーのブラウザではなくサーバー上で実行される処理のことです。API キーをサーバーに置くことで、ユーザーにキーが見えない安全な構成が作れます。
⚠️ この講座を進めるか迷った場合
Vercel で動いているアプリがある場合は、まず Vercel での運用を続けてください。Cloud Run は必要になったときに取り組む内容です。
Phase 1: Google Cloud の準備
STEP 1-1: Google Cloud プロジェクトの作成
Google Cloud のプロジェクトは「作業スペース」のようなものです。リソース・課金・権限がプロジェクト単位で管理されます。
【Windows 版】
- ブラウザで https://console.cloud.google.com を開く
- Google アカウントでログイン
- 画面上部のプロジェクト選択プルダウン → 「新しいプロジェクト」
- プロジェクト名を入力(例:
my-app-production) - 「作成」をクリック
- 作成したプロジェクトが選択されていることを確認する
【Mac 版】
手順は Windows 版と同一。ブラウザ上の操作のため差異なし。
⚠️ エラーが出た場合
プロジェクトが作成できない場合
- 同じ Google アカウントでプロジェクトを多数作成している場合は上限に達している可能性がある
- 組織アカウント(G Suite 等)の場合は管理者の許可が必要な場合がある
STEP 1-2: 請求先アカウントの設定と $300 無料クレジット
クレジットカードを登録しますが、無料トライアル中は請求されません。新規登録の場合、$300 分の無料クレジット(90 日間有効)が自動付与されます。
【Windows 版 / Mac 版 共通】
- Google Cloud コンソール → 左メニュー「お支払い」
- 「請求先アカウントにリンク」をクリック
- 「請求先アカウントの作成」→ 国・通貨を設定
- クレジットカード情報を入力
- $300 の無料クレジットが付与されることを確認
| シナリオ | 月間アクセス数 | 推定月額費用 |
|---|---|---|
| 開発・テスト中 | ほぼゼロ | ¥0〜¥100 |
| 個人ポートフォリオ | 〜1,000 リクエスト | ¥100〜¥500 |
| 小規模サービス | 〜10 万リクエスト | ¥500〜¥3,000 |
| 中規模サービス | 〜100 万リクエスト | ¥3,000〜¥15,000 |
⚠️ エラーが出た場合
請求先の設定でエラーが出る場合は、カード番号・有効期限・セキュリティコードを再確認してください。海外発行のカードや一部のデビットカードは使用できない場合があります。
STEP 1-3: 予算アラートの設定(重要)
意図しない課金を防ぐために、必ず予算アラートを設定してください。予算アラートは「自動的にサービスを停止する」ものではなく「メールで通知する」ものです。アラートを受け取ったらコンソールで状況を確認してください。
【Windows 版 / Mac 版 共通】
- Google Cloud コンソール → 左メニュー「お支払い」→「予算とアラート」
- 「予算を作成」をクリック
- 設定内容:
- 対象: 作成したプロジェクトを選択
- 予算金額: 月 1,000 円または 2,000 円(学習用途に合わせて設定)
- アラートのしきい値: 50% / 90% / 100% で通知するよう設定
- 通知先メールアドレス: 自分の Gmail アドレスを入力
- 「完了」をクリック
⚠️ エラーが出た場合
予算アラートが設定できない場合は、請求先アカウントが正しく設定されているか確認してください(STEP 1-2)。
STEP 1-4: 必要な API の有効化コマンド
Cloud Run と Artifact Registry を使うために必要な API を有効化します。
【Windows 版】
Google Cloud コンソール上部の「Cloud Shell を有効にする」アイコンをクリックするか、gcloud CLI をローカルにインストールして以下を実行します。
gcloud services enable run.googleapis.com gcloud services enable artifactregistry.googleapis.com gcloud services enable cloudbuild.googleapis.com gcloud services enable secretmanager.googleapis.com
ローカルに gcloud CLI をインストールする場合
# インストール後、コマンドプロンプトまたはPowerShellで実行 gcloud init gcloud auth login gcloud config set project YOUR_PROJECT_ID
【Mac 版】
# Homebrew 経由でインストール brew install --cask google-cloud-sdk gcloud init gcloud auth login gcloud config set project YOUR_PROJECT_ID
⚠️ エラーが出た場合
gcloud: command not found と表示される場合
- gcloud CLI が正しくインストールされていない
- Windows の場合: インストール後に新しいコマンドプロンプトを開く
- Mac の場合:
source ~/.zshrcまたはsource ~/.bash_profileを実行して PATH を再読み込みする
Phase 2: Docker Desktop のインストールと基本操作
STEP 2-1: Docker Desktop のインストール
Docker は「アプリと動作環境をまとめた箱(コンテナ)」を作るツールです。この箱ごとサーバーに送ることで、「手元では動くのにサーバーでは動かない」問題をなくせます。
【Windows 版】
- https://www.docker.com/products/docker-desktop にアクセス
- 「Download for Windows」をクリック
- ダウンロードしたインストーラーを実行
- 「Use WSL 2 instead of Hyper-V」のオプションが出た場合は WSL 2 を選択(推奨)
- インストール完了後、PC を再起動
- Docker Desktop を起動して、タスクトレイに Docker のアイコンが表示されることを確認
docker --version docker compose version
【Mac 版】
- 同サイトで「Download for Mac」をクリック(Apple Silicon と Intel で異なるインストーラーがある)
.dmgファイルを開いて Applications フォルダにドラッグ- Docker Desktop を起動
⚠️ エラーが出た場合
Windows: WSL 2 が有効になっていないエラー
PowerShell を管理者として開いて以下を実行:
wsl --install wsl --set-default-version 2
PC を再起動してから Docker Desktop を起動し直す。
permission denied while trying to connect to the Docker daemon
Docker Desktop が起動しているか確認してください。タスクトレイ(Windows)またはメニューバー(Mac)に Docker のアイコンがあるか確認してください。
STEP 2-2: Dockerfile の作成(マルチステージビルド)
Vite で作成した SPA アプリの Dockerfile を作成します。「マルチステージビルド」は2段階の処理です。1段目で Node.js を使ってビルド、2段目で nginx という Web サーバーで完成ファイルだけを提供します。これにより最終イメージに Node.js が含まれず、軽量で安全になります。
【Windows 版 / Mac 版 共通】
プロジェクトのルートディレクトリに Dockerfile というファイルを作成する(Cursor で開いて作成可):
# ---- Stage 1: Build ---- FROM node:20-alpine AS builder WORKDIR /app # 依存関係のインストール(キャッシュ最適化) COPY package*.json ./ RUN npm ci # アプリのビルド COPY . . RUN npm run build # ---- Stage 2: Serve ---- FROM nginx:alpine # nginx の設定ファイルをコピー(STEP 2-3 で作成) COPY nginx.conf /etc/nginx/conf.d/default.conf # ビルド成果物を nginx の公開ディレクトリにコピー COPY --from=builder /app/dist /usr/share/nginx/html EXPOSE 8080 CMD ["nginx", "-g", "daemon off;"]
⚠️ エラーが出た場合
Dockerfile の構文エラーが出る場合
ファイル名が Dockerfile(拡張子なし)であることを確認してください。Dockerfile.txt などになっていると認識されません。
STEP 2-3: nginx.conf の作成(SPA 対応)
React Router などの SPA ルーティングに対応する nginx の設定ファイルを作成します。try_files $uri $uri/ /index.html; がないと、直接 URL にアクセスした際に 404 エラーになります。
【Windows 版 / Mac 版 共通】
プロジェクトのルートディレクトリに nginx.conf を作成する:
server {
listen 8080;
server_name _;
root /usr/share/nginx/html;
index index.html;
# SPA 用: 存在しないパスは index.html に転送
location / {
try_files $uri $uri/ /index.html;
}
# キャッシュ設定: ハッシュ付きのアセットは長期キャッシュ
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
# ヘルスチェック(Cloud Run 用)
location /health {
return 200 'OK';
add_header Content-Type text/plain;
}
}
⚠️ エラーが出た場合
nginx がポート 8080 でリッスンするように設定されています。Cloud Run のデプロイコマンドでも --port 8080 を指定してください(STEP 4-1 参照)。
STEP 2-4: ローカルでの Docker ビルドとテスト
デプロイ前にローカルで動作確認します。
【Windows 版】
コマンドプロンプトまたは PowerShell でプロジェクトのルートに移動し:
# イメージをビルド docker build -t my-app:local . # コンテナを起動してテスト docker run -p 8080:8080 --name my-app-test my-app:local
ブラウザで http://localhost:8080 にアクセスしてアプリが表示されることを確認する。
# 確認後、コンテナを停止・削除する docker stop my-app-test docker rm my-app-test
【Mac 版】
ターミナルで同じコマンドを実行する。
⚠️ エラーが出た場合
docker build が失敗する場合
- Docker Desktop が起動しているか確認する
package.jsonがプロジェクトルートにあるか確認するnpm run buildをローカルで実行してビルドエラーがないか先に確認する- エラーログをコピーして Cursor または Claude.ai に貼り付けて修正を依頼する
Phase 3: Artifact Registry へのイメージ登録
STEP 3-1: Artifact Registry リポジトリの作成
【Windows 版 / Mac 版 共通】
# リポジトリを作成(リージョンは asia-northeast1 = 東京を推奨) gcloud artifacts repositories create my-app-repo \ --repository-format=docker \ --location=asia-northeast1 \ --description="Docker images for my app"
または Google Cloud コンソール → 「Artifact Registry」→「リポジトリを作成」から GUI で作成することもできます。
⚠️ エラーが出た場合
Artifact Registry API が有効になっていない場合は STEP 1-4 の API 有効化コマンドを再実行してください。
STEP 3-2: Docker 認証設定
【Windows 版】
gcloud auth configure-docker asia-northeast1-docker.pkg.dev
Docker configuration file updated. と表示されれば成功。
⚠️ エラーが出た場合
認証エラーが発生する場合は以下を実行:
gcloud auth login gcloud auth configure-docker asia-northeast1-docker.pkg.dev
STEP 3-3: イメージのタグ付けと push
tag は Docker イメージに「どこに送るか」という宛先ラベルを付ける作業です。push は実際にそのレジストリ(倉庫)にイメージを送信します。
【Windows 版 / Mac 版 共通】
YOUR_PROJECT_ID は自分のプロジェクト ID に置き換えてください(Google Cloud コンソールの上部に表示されています)。
# イメージにタグを付ける docker tag my-app:local \ asia-northeast1-docker.pkg.dev/YOUR_PROJECT_ID/my-app-repo/my-app:latest # Artifact Registry に Push docker push \ asia-northeast1-docker.pkg.dev/YOUR_PROJECT_ID/my-app-repo/my-app:latest
Push 完了後、Google Cloud コンソールの「Artifact Registry」でイメージが登録されていることを確認する。
⚠️ エラーが出た場合
UNAUTHORIZED: Invalid credentials の場合
Docker 認証が切れています。STEP 3-2 の gcloud auth configure-docker を再実行してください。
Phase 4: Cloud Run へのデプロイ
STEP 4-1: CLI からのデプロイコマンド
デプロイが完了すると Service URL が表示されます。その URL でアプリが公開されています。
【Windows 版 / Mac 版 共通】
gcloud run deploy my-app \
--image asia-northeast1-docker.pkg.dev/YOUR_PROJECT_ID/my-app-repo/my-app:latest \
--platform managed \
--region asia-northeast1 \
--allow-unauthenticated \
--port 8080
| オプション | 意味 |
|---|---|
--allow-unauthenticated | 誰でもアクセス可能にする(公開アプリの場合) |
--port 8080 | nginx.conf で設定したポート番号に合わせる |
⚠️ エラーが出た場合
デプロイに失敗する場合
gcloud run services describe my-app --region asia-northeast1
でエラー詳細を確認してください。
PERMISSION_DENIED エラーの場合
Cloud Run API が有効でない可能性があります。STEP 1-4 の API 有効化コマンドを実行してください。
STEP 4-2: 環境変数と Secret Manager の設定
Secret Manager を使うと、API キーがコードや Docker イメージに含まれず、サーバーが起動するときだけ読み込まれます。これが最も安全な方法です。
【Windows 版 / Mac 版 共通】
# Secret Manager にシークレットを作成 echo -n "YOUR_ACTUAL_API_KEY" | gcloud secrets create GEMINI_API_KEY \ --data-file=- \ --replication-policy=automatic # Cloud Run のサービスアカウントを確認 gcloud run services describe my-app \ --region asia-northeast1 \ --format "value(spec.template.spec.serviceAccountName)" # Secret Manager アクセス権を付与(SERVICE_ACCOUNT は上記コマンドで取得した値) gcloud secrets add-iam-policy-binding GEMINI_API_KEY \ --member="serviceAccount:SERVICE_ACCOUNT" \ --role="roles/secretmanager.secretAccessor" # Cloud Run のデプロイに Secret を環境変数として設定 gcloud run services update my-app \ --region asia-northeast1 \ --update-secrets=GEMINI_API_KEY=GEMINI_API_KEY:latest
⚠️ エラーが出た場合
「The user does not have permission to access secret」の場合
Cloud Run のサービスアカウントに Secret Manager のアクセス権が付与されていません。IAM 設定を確認して gcloud secrets add-iam-policy-binding を再実行してください。
STEP 4-3: スケーリング設定(最小0インスタンスでコスト最適化)
アクセスがないときはコンテナを0台に落とすことで費用を最小化できます。最小0インスタンスにすると初回アクセス時に数秒の「コールドスタート」が発生します。
【Windows 版 / Mac 版 共通】
gcloud run services update my-app \
--region asia-northeast1 \
--min-instances 0 \
--max-instances 10 \
--concurrency 80 \
--cpu 1 \
--memory 512Mi
| 設定項目 | 推奨値 | 説明 |
|---|---|---|
--min-instances | 0 | アクセスがないときはコンテナゼロ(コスト最小) |
--max-instances | 10 | トラフィック増加時の上限 |
--concurrency | 80 | 1コンテナが同時に処理するリクエスト数 |
--cpu | 1 | CPU コア数 |
--memory | 512Mi | メモリ量 |
⚠️ エラーが出た場合
コールドスタートが遅い(5秒以上)の場合
最小インスタンスを0から1に変更すると改善しますが、月額 1,500〜3,000 円程度の費用が追加で発生します。
gcloud run services update my-app \
--region asia-northeast1 \
--min-instances 1
STEP 4-4: 独自ドメインの設定
【Windows 版 / Mac 版 共通】
- Google Cloud コンソール → 「Cloud Run」→ サービスを選択 → 「カスタムドメインを管理」
- 「ドメインをマップ」をクリック
- 取得したドメイン名を入力
- Verification が必要な場合は DNS TXT レコードを追加してドメイン所有を証明する
- 表示される DNS レコード(A レコードまたは CNAME)をドメインのレジストラに設定する
DNS 設定の確認は講座06 STEP 4-3 の whatsmydns.net と同じ手順で行います。
⚠️ エラーが出た場合
DNS の反映には最大 72 時間かかります。設定直後に確認して反映されていなくても、数時間後に再確認してください。
Phase 5: 更新・運用フロー(デプロイシェルスクリプト)
STEP 5-1: コード修正から本番反映までの標準フロー
タグに日時を含めることで、どのバージョンのイメージが本番で動いているかを追跡できます。問題が起きたら古いタグのイメージに戻すことでロールバックできます。
【Windows 版 / Mac 版 共通】
# 1. コードを修正後、Docker イメージを再ビルド docker build -t my-app:local . # 2. ローカルで動作確認(任意) docker run -p 8080:8080 my-app:local # 3. 新しいタグ(バージョン管理のためにタグを使う) DEPLOY_TIME=$(date +%Y%m%d-%H%M%S) docker tag my-app:local \ asia-northeast1-docker.pkg.dev/YOUR_PROJECT_ID/my-app-repo/my-app:$DEPLOY_TIME docker tag my-app:local \ asia-northeast1-docker.pkg.dev/YOUR_PROJECT_ID/my-app-repo/my-app:latest # 4. Artifact Registry に Push docker push asia-northeast1-docker.pkg.dev/YOUR_PROJECT_ID/my-app-repo/my-app:$DEPLOY_TIME docker push asia-northeast1-docker.pkg.dev/YOUR_PROJECT_ID/my-app-repo/my-app:latest # 5. Cloud Run にデプロイ gcloud run deploy my-app \ --image asia-northeast1-docker.pkg.dev/YOUR_PROJECT_ID/my-app-repo/my-app:latest \ --region asia-northeast1
シェルスクリプトにまとめる(推奨)
プロジェクトルートに deploy.sh を作成すると毎回のデプロイが1コマンドで完了します:
#!/bin/bash set -e PROJECT_ID="YOUR_PROJECT_ID" SERVICE_NAME="my-app" REGION="asia-northeast1" REPO="my-app-repo" IMAGE_BASE="$REGION-docker.pkg.dev/$PROJECT_ID/$REPO/$SERVICE_NAME" TAG=$(date +%Y%m%d-%H%M%S) echo "Building Docker image..." docker build -t $SERVICE_NAME:local . echo "Tagging and pushing image..." docker tag $SERVICE_NAME:local $IMAGE_BASE:$TAG docker tag $SERVICE_NAME:local $IMAGE_BASE:latest docker push $IMAGE_BASE:$TAG docker push $IMAGE_BASE:latest echo "Deploying to Cloud Run..." gcloud run deploy $SERVICE_NAME \ --image $IMAGE_BASE:latest \ --region $REGION echo "Deploy complete!"
chmod +x deploy.sh
./deploy.sh
⚠️ エラーが出た場合
Windows の PowerShell で $DEPLOY_TIME が展開されない場合
PowerShell では変数展開の記法が異なります。Git Bash を使って実行するか、スクリプト内の変数部分を手動で書き換えてください。
ビルドが遅い場合
Dockerfile の依存関係インストール順序を確認してください。COPY package*.json ./ を先に実行してから npm ci することでキャッシュが効きます。
STEP 5-2: よくあるエラー一覧と対処方法
| エラーメッセージ | 原因 | 対処方法 |
|---|---|---|
permission denied while trying to connect to the Docker daemon | Docker が起動していない | Docker Desktop を起動する |
UNAUTHORIZED: Invalid credentials | Docker 認証が切れている | gcloud auth configure-docker を再実行 |
The user does not have permission to access secret | Secret Manager の権限不足 | STEP 4-2 の IAM 設定を確認 |
Container failed to start | ポート番号の不一致 | --port と nginx.conf の listen が同じ番号か確認 |
ERROR: (gcloud.run.deploy) PERMISSION_DENIED | Cloud Run API が有効でない | STEP 1-4 の API 有効化コマンドを実行 |
⚠️ 上記に当てはまらないエラーが出た場合
エラーメッセージ全体をコピーして Cursor または Claude.ai に貼り付けて修正を依頼してください。「Cloud Run のデプロイで以下のエラーが出ました。対処法を教えてください。」と説明を加えると回答精度が上がります。