Next.jsアプリをGCP Cloud Runにデプロイする際、毎回「あれ、どのAPIを有効化するんだっけ?」「サービスアカウントの権限設定はどうだったかな?」と忘れてしまうことがありました。
特に新規プロジェクトを立ち上げる際、GCPプロジェクトの作成からGitHub Actionsによる自動デプロイまでの一連の流れを毎回調べ直すのは非効率です。
そこで、自分自身の備忘録として、また同じ課題を抱えるエンジニアの役に立つように、この記事をまとめることにしました。
※この記事は実際に運用しているアプリケーションをベースに書いていますが、すでに何度も改修を繰り返しており、記憶ベースで書いている部分も含まれます。そのため、このフロー通りに進めれば100%スムーズにデプロイできることを保証するものではありません。環境やプロジェクトの状況によっては、追加の設定や調整が必要になる可能性があります。
この記事を読み終えると、以下のことができるようになります:
以下のトピックは記事が長くなりすぎるため、別記事で詳しく解説予定です:
この記事で作成するファイルは以下の通りです:
my-nextjs-app/
├── .github/
│ └── workflows/
│ └── deploy.yml # 🆕 GitHub Actionsワークフロー
├── app/
│ ├── layout.tsx
│ └── page.tsx
├── public/
├── Dockerfile # 🆕 Dockerイメージ定義
├── cloudbuild.yml # 🆕 Cloud Build設定
├── next.config.ts # ✏️ 修正(output: 'standalone'を追加)
├── package.json
├── pnpm-lock.yaml
└── tsconfig.json
新規作成するファイルは3つ、修正するファイルは1つです。
my-nextjs-app
(任意)my-nextjs-app-12345
(グローバルで一意である必要があります)作成したプロジェクトのダッシュボードで以下を確認してメモしておきます:
my-nextjs-app-12345
123456789012
(後で使用します)ターミナルで以下を実行してプロジェクトを切り替えます:
# GCPにログイン(初回のみ)
gcloud auth login
# プロジェクトを設定
gcloud config set project my-nextjs-app-12345
# 設定確認
gcloud config list
GitHub ActionsからCloud Runにデプロイするには、以下の4つのAPIを有効化する必要があります。
gcloud services enable \
run.googleapis.com \
cloudbuild.googleapis.com \
containerregistry.googleapis.com \
artifactregistry.googleapis.com
API | 役割 |
---|---|
Cloud Run API ( run.googleapis.com ) | Cloud Runサービスの作成・管理・デプロイに必要 |
Cloud Build API ( cloudbuild.googleapis.com ) | Dockerイメージのビルドプロセスを実行 |
Container Registry API ( containerregistry.googleapis.com ) | ビルドしたDockerイメージを保存(GCR) |
Artifact Registry API ( artifactregistry.googleapis.com ) | 新世代のイメージレジストリ(推奨) |
gcloud services list --enabled
上記4つのAPIが表示されればOKです。
GitHub ActionsとCloud Buildがリソースにアクセスできるよう、サービスアカウントを作成して権限を付与します。
gcloud iam service-accounts create github-actions \
--display-name="GitHub Actions Deployment" \
--project=my-nextjs-app-12345
以下の4つのロールを付与します:
# 1. Cloud Run管理者(サービスのデプロイ・管理)
gcloud projects add-iam-policy-binding my-nextjs-app-12345 \
--member="serviceAccount:github-actions@my-nextjs-app-12345.iam.gserviceaccount.com" \
--role="roles/run.admin"
# 2. Cloud Build編集者(ビルドの実行)
gcloud projects add-iam-policy-binding my-nextjs-app-12345 \
--member="serviceAccount:github-actions@my-nextjs-app-12345.iam.gserviceaccount.com" \
--role="roles/cloudbuild.builds.editor"
# 3. Storage管理者(イメージのプッシュ・取得)
gcloud projects add-iam-policy-binding my-nextjs-app-12345 \
--member="serviceAccount:github-actions@my-nextjs-app-12345.iam.gserviceaccount.com" \
--role="roles/storage.admin"
# 4. サービスアカウントユーザー(他のサービスアカウントを使用)
gcloud projects add-iam-policy-binding my-nextjs-app-12345 \
--member="serviceAccount:github-actions@my-nextjs-app-12345.iam.gserviceaccount.com" \
--role="roles/iam.serviceAccountUser"
GitHub ActionsからGCPにアクセスするための認証鍵を生成します:
gcloud iam service-accounts keys create ~/my-nextjs-app-github-actions-key.json \
--iam-account=github-actions@my-nextjs-app-12345.iam.gserviceaccount.com \
--project=my-nextjs-app-12345
生成された~/my-nextjs-app-github-actions-key.json
は次のステップで使用します。
Cloud BuildがCloud Runにデプロイできるよう、Cloud Buildのデフォルトサービスアカウントにも権限を付与します:
# プロジェクト番号を設定(手順1-2で控えた番号)
PROJECT_NUMBER="123456789012"
# Cloud Run管理者権限を付与
gcloud projects add-iam-policy-binding my-nextjs-app-12345 \
--member="serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com" \
--role="roles/run.admin"
# サービスアカウントユーザー権限を付与
gcloud projects add-iam-policy-binding my-nextjs-app-12345 \
--member="serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com" \
--role="roles/iam.serviceAccountUser"
生成したJSON鍵をGitHub Secretsに安全に保存します。
cat ~/my-nextjs-app-github-actions-key.json
出力された内容全体をコピーします。
GCP_SA_KEY
{
"type": "service_account",
"project_id": "my-nextjs-app-12345",
"private_key_id": "...",
"private_key": "-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n",
...
}
GCP_PROJECT_ID
my-nextjs-app-12345
(あなたのプロジェクトID)Cloud Runで動作させるためにnext.config.ts
を修正します:
// next.config.ts
import type { NextConfig } from "next";
const nextConfig: NextConfig = {
// Cloud Run用にスタンドアロンビルドを有効化
output: 'standalone',
// ポート設定(Cloud Runはデフォルトで8080を使用)
// 環境変数PORTが設定されていればそれを使用
};
export default nextConfig;
プロジェクトルートにDockerfile
を作成します:
# Dockerfile
# マルチステージビルド: 依存関係のインストール
FROM node:24-alpine AS deps
WORKDIR /app
COPY package.json pnpm-lock.yaml ./
RUN corepack enable pnpm && pnpm install --frozen-lockfile --prod
# マルチステージビルド: アプリケーションのビルド
FROM node:24-alpine AS builder
WORKDIR /app
COPY package.json pnpm-lock.yaml ./
RUN corepack enable pnpm && pnpm install --frozen-lockfile
COPY . .
# ビルド時環境変数の設定
ARG APP_ENV
ENV APP_ENV=$APP_ENV
# Next.jsビルド(NODE_ENVは常にproduction)
ENV NODE_ENV=production
RUN pnpm run build
# マルチステージビルド: 実行用の軽量イメージ
FROM node:24-alpine AS runner
WORKDIR /app
# 本番環境の設定
ENV NODE_ENV=production
# セキュリティ: 非rootユーザーでの実行
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs
# Standalone出力をコピー
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
# 非rootユーザーに切り替え
USER nextjs
# Cloud Runのデフォルトポート
EXPOSE 8080
# 環境変数でポートを設定
ENV PORT=8080
ENV HOSTNAME="0.0.0.0"
# アプリケーションの起動
CMD ["node", "server.js"]
Cloud Buildの設定ファイルを作成します:
# cloudbuild.yml
steps:
# Dockerイメージのビルド
- name: 'gcr.io/cloud-builders/docker'
args:
- 'build'
- '-t'
- 'gcr.io/$PROJECT_ID/${_SERVICE_NAME}:latest'
- '-t'
- 'gcr.io/$PROJECT_ID/${_SERVICE_NAME}:$SHORT_SHA'
- '.'
# GCRにイメージをプッシュ
- name: 'gcr.io/cloud-builders/docker'
args:
- 'push'
- 'gcr.io/$PROJECT_ID/${_SERVICE_NAME}:latest'
# Cloud Runにデプロイ
- name: 'gcr.io/cloud-builders/gcloud'
args:
- 'run'
- 'deploy'
- '${_SERVICE_NAME}'
- '--image'
- 'gcr.io/$PROJECT_ID/${_SERVICE_NAME}:latest'
- '--platform'
- 'managed'
- '--region'
- 'asia-northeast1'
- '--allow-unauthenticated'
- '--memory'
- '1Gi'
- '--cpu'
- '1'
- '--set-env-vars'
- 'APP_ENV=${_APP_ENV}'
# ビルド設定
options:
machineType: 'E2_HIGHCPU_8'
logging: CLOUD_LOGGING_ONLY
timeout: '1200s'
# 置換変数(GitHub Actionsから渡される)
substitutions:
_SERVICE_NAME: 'my-nextjs-app'
_APP_ENV: 'production'
.github/workflows/deploy.yml
を作成します:
# .github/workflows/deploy.yml
name: Deploy to Cloud Run
on:
push:
branches:
- main # mainブランチへのpushでデプロイ
jobs:
deploy:
runs-on: ubuntu-latest
steps:
# コードのチェックアウト
- name: Checkout code
uses: actions/checkout@v4
# GCPへの認証
- name: Authenticate to Google Cloud
uses: google-github-actions/auth@v2
with:
credentials_json: ${{ secrets.GCP_SA_KEY }}
# gcloud CLIのセットアップ
- name: Set up Google Cloud CLI
uses: google-github-actions/setup-gcloud@v2
with:
project_id: ${{ secrets.GCP_PROJECT_ID }}
# Dockerの認証設定
- name: Configure Docker to use gcloud
run: |
gcloud auth configure-docker
# Cloud Buildでビルド&デプロイ
- name: Deploy to Cloud Run
run: |
gcloud builds submit \
--config cloudbuild.yml \
--substitutions _SERVICE_NAME=my-nextjs-app,_APP_ENV=production \
--project ${{ secrets.GCP_PROJECT_ID }}
# デプロイ完了後のURL表示
- name: Get deployment URL
run: |
URL=$(gcloud run services describe my-nextjs-app \
--region asia-northeast1 \
--format 'value(status.url)')
echo "🚀 Deployment successful!"
echo "URL: $URL"
Dockerfile
、cloudbuild.yml
、.github/workflows/deploy.yml
)をコミットgit add .
git commit -m "feat: add Cloud Run deployment configuration"
git push origin main
デプロイが成功すると、GitHub Actionsのログに以下のようなURLが表示されます:
🚀 Deployment successful!
URL: https://my-nextjs-app-xxxxx-an.a.run.app
このURLにアクセスしてアプリが正常に動作していることを確認します。
# サービス一覧を表示
gcloud run services list --region=asia-northeast1
# サービスの詳細を表示
gcloud run services describe my-nextjs-app --region=asia-northeast1
この記事では、GCPプロジェクトの作成からNext.jsアプリのCloud Runへの自動デプロイまでを解説しました。
コード変更 → git push → GitHub Actions起動
↓
GCP認証 → Cloud Build実行
↓
Dockerイメージビルド → GCRにプッシュ
↓
Cloud Runにデプロイ → 完了
最終更新: 2025年10月12日