# Vercel デプロイ・CI/CD ガイド：プレビュー・Promote・Instant Rollback・Rolling Releases を本番品質で

> Vercel公式に忠実なデプロイ運用ガイド。Git連携の自動プレビュー、不変デプロイとProduction Promote、Instant Rollback、Rolling Releases（段階配信・カナリア比較・Skew Protection・REST API・vcrrForceCanary）、GitHub Actionsでの--prebuilt CI/CDとOIDC鍵レス、vercel.ts設定までを実コマンド・実コードで解説します。

- 公開日: 2026-06-28
- 著者: 友田 陽大
- タグ: Vercel, CI/CD, デプロイ, Next.js, 可観測性, アーキテクチャ設計, TypeScript
- URL: https://tomodahinata.com/blog/vercel-deployments-cicd-rollback-rolling-releases-guide
- カテゴリ: Vercel 本番運用
- 総合ガイド: https://tomodahinata.com/blog/vercel-production-platform-guide

## 要点

- Vercelのデプロイは4つの安全弁——ブランチ/PRごとの自動プレビューURL、検証済みデプロイのProduction Promote、不変デプロイへのInstant Rollback、Rolling Releasesのカナリア段階配信。本番事故を『出す前・出した後』の両面で防ぐ
- Rolling ReleasesはPro（1プロジェクト）とEnterprise。2つ以上のステージを設定し各ステージは前より大きい比率、最終ステージは必ず100%。Speed Insightsでカナリアと現行を比較し、手動または時間経過で昇格、問題があればInstant Rollbackで中断
- Rolling Releasesには必ずSkew Protectionを併用する。カナリアと現行で『ページのバージョン』と『バックエンドAPIのバージョン』が食い違う事故を防ぎ、どのデプロイに当たったユーザーも整合したバックエンドと通信させる
- CI/CDはvercel build --prebuilt + vercel deploy --prebuiltで『一度ビルドした成果物をそのまま昇格』。GitHub ActionsからはOIDCトークン連携で長命の鍵を置かずにデプロイする
- vcrrForceCanary=true/vcrrForceStable=trueでカナリア/現行を強制し、本番トラフィックを当てずに検証できる。Rolling ReleasesはREST API（approve-stage/complete/rollback）で自動化できる

---

デプロイは「git push したら本番に出た」で終わらせると、いつか必ず事故ります。Vercel の真価は、**本番事故を「出す前」と「出した後」の両面で抑え込む安全弁**を最初から備えている点にあります。この記事は、[Rolling Releases](https://vercel.com/docs/rolling-releases) や [Instant Rollback](https://vercel.com/docs/instant-rollback) などの公式仕様に忠実に、**安全に出す・即座に戻す**デプロイ運用を実コマンドでまとめます。

全体像は [Vercel 本番運用ガイド](/blog/vercel-production-platform-guide) を参照してください。本稿は「どう出して、どう戻すか」に集中します。

---

## 4つの安全弁

| 安全弁 | タイミング | 役割 |
|---|---|---|
| **プレビューURL** | 出す前 | ブランチ/PR ごとに本番同等の独立URL。レビュー・QA・ステークホルダー確認 |
| **Production Promote** | 出す瞬間 | 検証済みデプロイを本番へ昇格。再ビルドせず成果物をそのまま |
| **Instant Rollback** | 出した後（問題時） | 不変な過去デプロイへ**即時**復帰 |
| **Rolling Releases** | 出す過程 | 新デプロイを段階配信（カナリア）し、メトリクスで判断 |

これらが効くのは、Vercel のデプロイが**不変（イミュータブル）なスナップショット**だからです。各デプロイは固有URLを持ち、過去のものも生き続けます。だから「戻す」は再デプロイではなく**ルーティングの切り替え**で、一瞬で済みます。

---

## プレビューデプロイ：レビューを本番品質の環境で

Git 連携すると、**プッシュのたびにプレビューデプロイ**が作られ、独立URLが発行されます。本番と同じビルド・同じ関数・同じエッジで動くので、「ローカルでは動いた」を潰せます。

```bash
# 手動でプレビューを作る（CLI）
vercel deploy
# → https://your-app-git-feature-xyz.vercel.app のような固有URL
```

プレビューは PR にコメントされ、レビュアーは実物を触って確認できます。E2E（Playwright 等）をプレビューURLに対して回すと、**マージ前**に回帰を捕まえられます（[Playwright E2E 設計](/blog/playwright-e2e-testing-production-design-guide)）。

> **プレビューも守る**：プレビューURLは公開です。ステージング相当の機密がある場合は、Vercel の**デプロイ保護（パスワード/SSO）**や [Firewall](/blog/vercel-firewall-waf-botid-ddos-security-guide) でアクセス制御します。

---

## 本番へ：Promote と Instant Rollback

### Production Promote

検証済みのプレビューデプロイを、**再ビルドせずに**本番へ昇格します。「ビルドした成果物 ＝ 本番に出る成果物」が保証され、ビルド差異による事故が消えます。

```bash
vercel promote <deployment-url-or-id>   # 本番へ昇格
```

### Instant Rollback

本番で問題が出たら、過去の本番デプロイへ**即時**戻します。不変デプロイなので、ビルドも待ちません。

```bash
vercel rollback <deployment-url-or-id>  # 指定デプロイへ即時復帰
# 引数なしなら直前の本番へ
```

> **ISR キャッシュも戻る**：ロールバックしても、過去デプロイの ISR キャッシュは purge されていないので、**生成済みコンテンツを失わず**に戻れます（[キャッシュ戦略](/blog/vercel-caching-isr-cache-components-ppr-guide)）。

---

## Rolling Releases：いきなり100%に出さない

「新デプロイを全ユーザーに一斉公開」は最もリスクが高い行為です。Rolling Releases は、**まず一部（例：5%）にだけ**新デプロイを流し、メトリクスを見ながら段階的に100%へ広げます（Pro は1プロジェクト、Enterprise はカスタム）。

### ステージ設計

有効化したら、**2つ以上のステージ**を設定します。各ステージはカナリアへ流す比率で、**後のステージほど大きく**、**最終ステージは必ず100%**。多くのプロジェクトは「1つの少数ステージ＋100%」の2段で足ります。

```
例）2段：  5%  → 100%
例）3段：  5%  →  25%  → 100%
```

各 promote 操作（git push の自動昇格・ダッシュボードの Promote・`vercel promote`）が**新しい Rolling Release を開始**します。進行中の Rolling Release があるときは、解決（完了 or 中断）するまで次は始まりません。

### カナリアを判断する

進行中は、デプロイ一覧でリリース候補が **"Canary"** バッジと流入比率で示され、**Observability タブの Rolling Releases セクション**で Vercel 計測のメトリクス（Speed Insights 等）をカナリア vs 現行で比較できます。良ければ次ステージへ「Advance」、最終ステージなら100%昇格して通常状態へ。ダメなら——

```
Abort（中断）/ Instant Rollback でベースデプロイへ戻す
```

### 必須：Skew Protection

Rolling Releases では、あるユーザーが**新旧どちらのページ**を受け取るか分かれます。このとき、ページから出る**バックエンドAPI呼び出しのバージョン**がページとズレると壊れます。**Skew Protection** は「どのデプロイに当たったユーザーも、そのページと**同じバージョンのバックエンド**と通信する」ことを保証します。

> 公式も「Rolling Releases には Skew Protection を強く推奨」と明記しています。**セットで有効化**してください。これを忘れると、配信中だけ再現する厄介なバグ（古いクライアントが新APIを叩く等）に悩まされます。

### 本番トラフィックなしで検証する

Rolling Release 中、URLに特殊なクエリを付けると、自分のセッションだけ強制的にカナリア／現行へ振れます。

- `?vcrrForceCanary=true` … 常にカナリア（0%設定のステージでもアクセス可）
- `?vcrrForceStable=true` … 常にベース（現行）

```bash
# カナリアだけを自分で確認（一般ユーザーには5%しか出していない状態で）
open "https://your-app.vercel.app/checkout?vcrrForceCanary=true"
```

> **注意**：`vcrrForceCanary=true` は誰でも付けられます。0% カナリアは既定で配信されませんが、**秘匿はされていません**。本当に隠したい機能は Rolling Releases ではなく[機能フラグ（Edge Config）](/blog/vercel-storage-blob-edge-config-marketplace-guide)や認可で守ります。

### REST API / CLI で自動化

Rolling Releases は API で制御でき、CI/CD に組み込めます。

| 操作 | エンドポイント |
|---|---|
| 設定取得/更新 | `GET`/`PATCH /v1/projects/{id}/rolling-release/config` |
| 次ステージへ | `POST /v1/projects/{id}/rolling-release/approve-stage` |
| 100%完了 | `POST /v1/projects/{id}/rolling-release/complete` |
| ロールバック | `POST /v1/projects/{id}/rollback/{deploymentId}` |

> **API での中断の注意**：進行中に config を無効化（PATCH/DELETE）しても、それだけでは現在の Rolling Release は止まりません（未来のリリースにのみ影響）。**`complete`（カナリアを100%）か `rollback`（ベースへ）**を別途呼ぶ必要があります。

---

## CI/CD：GitHub Actions で再ビルドなし昇格

Vercel の Git 連携だけでも CI/CD は回りますが、**独自のテスト/ゲートを挟みたい**ときは GitHub Actions から `--prebuilt` で出すのが定石です。「一度ビルドした成果物をそのまま本番へ」昇格でき、ビルド差異とビルド時間を消せます。

```yaml
# .github/workflows/deploy-production.yml
name: Deploy Production
on:
  push:
    branches: [main]

permissions:
  contents: read
  id-token: write   # OIDC（鍵レス）に必要

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with: { node-version: 24 }

      - run: npm ci

      # 品質ゲート（型・lint・テスト）— 通らなければ出さない
      - run: npm run lint && npm run test && npx tsc --noEmit

      - run: npm i -g vercel@latest

      # ① 環境情報を取得 → ② ビルド → ③ 成果物をそのままデプロイ
      - run: vercel pull --yes --environment=production --token=${{ secrets.VERCEL_TOKEN }}
      - run: vercel build --prod --token=${{ secrets.VERCEL_TOKEN }}
      - run: vercel deploy --prebuilt --prod --token=${{ secrets.VERCEL_TOKEN }}
```

> **鍵レス（OIDC）が2026年の標準**：外部クラウド（AWS 等）の認証情報を CI に置かず、GitHub の OIDC トークンで一時クレデンシャルを得ます。Vercel の OIDC 連携を使うと、長命のアクセスキーをシークレットに保管せずに済みます（[OIDC 鍵レス CI/CD の考え方](/blog/github-actions-oidc-keyless-cicd-aws-gcp-guide)）。`VERCEL_TOKEN` 自体もスコープを絞り、ローテーションします。

---

## 設定は vercel.ts（型安全・動的）

ビルド・ルーティング・ヘッダ・Cron・関数設定は **`vercel.ts`** で型安全に宣言できます。`vercel.json` と違い**ビルド時に実行**されるので、環境変数で条件分岐したり API から設定を取得したりできます（どちらか一方のみ）。

```ts
// vercel.ts
import { routes, deploymentEnv, type VercelConfig } from "@vercel/config/v1";

const isProd = deploymentEnv.VERCEL_ENV === "production";

export const config: VercelConfig = {
  framework: "nextjs",
  buildCommand: "npm run build",
  // 本番だけ別バックエンドへ rewrite するような動的設定が書ける
  rewrites: [
    routes.rewrite("/api/(.*)", isProd
      ? "https://api.example.com/$1"
      : "https://staging-api.example.com/$1"),
  ],
  headers: [
    routes.cacheControl("/assets/(.*)", { public: true, maxAge: "1 year", immutable: true }),
  ],
  crons: [{ path: "/api/cron/cleanup", schedule: "0 0 * * *" }],
};
```

`@vercel/config` を入れ、`config` を export するだけです。`vercel.json` から移行するなら、内容を `config` にコピーしてから動的化していきます。

---

## 本番チェックリスト（デプロイ）

- [ ] プレビューURLで**レビュー・E2E**を回してからマージ
- [ ] CI に**型・lint・テストの品質ゲート**を置き、通らなければ出さない
- [ ] `--prebuilt` で**再ビルドなし昇格**、ビルド差異を排除
- [ ] CI 認証は **OIDC 鍵レス**、`VERCEL_TOKEN` はスコープ最小＋ローテーション
- [ ] 重要リリースは **Rolling Releases** で段階配信
- [ ] Rolling Releases には **Skew Protection を必ず併用**
- [ ] **Instant Rollback の手順**をチームで共有（誰でも即戻せる）
- [ ] 設定は `vercel.ts`/`vercel.json` のどちらか一方に統一

---

## まとめ

Vercel のデプロイ運用は、**不変デプロイ**という土台の上に4つの安全弁を重ねる設計です。

1. **プレビュー**で出す前に捕まえる
2. **Promote**で成果物をそのまま昇格
3. **Instant Rollback**で出した後も一瞬で戻せる
4. **Rolling Releases ＋ Skew Protection**で段階的に・整合して広げる
5. CI/CD は **`--prebuilt` ＋ OIDC 鍵レス**で安全・高速に

次は、出した本番の入口を守る [Firewall・WAF・BotID ガイド](/blog/vercel-firewall-waf-botid-ddos-security-guide) へ。

> 本記事は [Rolling Releases](https://vercel.com/docs/rolling-releases) / [Instant Rollback](https://vercel.com/docs/instant-rollback) / [Vercel CLI](https://vercel.com/docs/cli) 公式ドキュメント（2026年6月時点）に基づきます。仕様は更新されるため、本番採用時は公式で最新値を確認してください。
