「Next.js を EC2 や ECS、あるいは Netlify で動かしているが、運用の手間とデプロイの遅さに疲れた。Vercel に移したい。でも止めたくない」——この相談は本当に多いです。移行はやり方さえ間違えなければ無停止で、しかもロールバックも一瞬です。逆に、ステートフルな依存を見落とすと本番で詰まります。
この記事は、自前ホスト(AWS/EC2/ECS/Amplify)や Netlify から Vercel へ無停止で移行する実践手順を、Vercel 公式ドキュメントに忠実にまとめます。移行先の本番運用の全体像は Vercel 本番運用ガイド を参照してください。
移行の大原則:DNS カットオーバーを最後にする
移行で最も多い事故は「いきなり本番ドメインを Vercel に向けて、動かない」。これを避ける鉄則は——
①Vercelにデプロイ(プレビューURLで動く状態を作る)
↓
②プレビューで本番同等の検証(並走)
↓
③本番ブランチへPromote(まだ独自ドメインは旧基盤)
↓
④DNSを切り替える(最後の一手)
↓
⑤問題があればDNSを戻すだけ=即ロールバック
DNS を最後の一手にすることで、切り替え前にいくらでも検証でき、問題時は DNS を戻すだけで旧基盤に復帰できます。
ステップ0:移行可否を見極める(最重要)
コードを動かす前に、「サーバー前提の依存」を棚卸しします。ここを飛ばすと本番で詰まります。Vercel はステートレスなサーバーレス基盤なので、以下は置き換えが必要です。
| 旧基盤での依存 | Vercel での置き換え |
|---|---|
| ローカルファイル書き込み(アップロード保存・生成PDF) | Vercel Blob(client upload) |
| 常駐プロセス / バックグラウンドワーカー | Cron Jobs / Queues / Workflows |
| 長時間処理(バッチ・動画変換、>数分) | Vercel Workflows(実行時間無制限)/ 外部ジョブ |
| WebSocket サーバー常駐 | SSE / 外部リアルタイム基盤(Ably/Pusher等)/ 別途常駐基盤 |
| VPC 内専用 DB(公開エンドポイントなし) | 公開+認証付きエンドポイント化、または Marketplace(Neon等)、Secure Compute(Ent) |
| インメモリのセッション/レート制限 | Redis(Upstash) / Edge Config / 外部ストア |
| 巨大なモノリス(>250MB バンドル) | 機能分割、または対象は別基盤に残す |
判断:標準的な Next.js(App Router、ステートレス、外部 DB)なら移行は容易。逆に「ファイルをローカルに書く」「常駐プロセスに依存」が深いほど、移行は再設計を伴います。ここを正直に評価するのが成否を分けます。
ステップ1:プロジェクトを Vercel に接続
Git 連携が最短です。リポジトリをインポートすると、プッシュごとにプレビューが作られます。
npm i -g vercel@latest
vercel login
vercel link # 既存プロジェクトに紐付け(or 新規作成)
vercel # プレビューデプロイを作成 → 固有URLで動作確認
フレームワークは自動検出されますが、ビルドコマンド・出力ディレクトリ・ルートディレクトリ(モノレポなら特に)を設定で確認します。モノレポは Turborepo のルート設定に注意。
ステップ2:環境変数とシークレットを移送
旧基盤の環境変数を、Vercel の**3環境(production / preview / development)**へ整理して移します。
# 本番のシークレットを production だけに登録
vercel env add DATABASE_URL production
vercel env add STRIPE_SECRET_KEY production
# プレビューには本番と別の値(ステージングDB等)を
vercel env add DATABASE_URL preview
# ローカル開発用をローカルへ同期
vercel env pull .env.local
移送時の必須チェック(環境変数ガイド):
NEXT_PUBLIC_接頭辞に機密を載せない(ブラウザに露出)。API キーは無印で。- 環境変数の変更は新しいデプロイにのみ適用される(既存デプロイは変わらない)。
- 外部クラウド(AWS S3/SES 等)へは、長命のアクセスキーを置かず OIDC 鍵レスへ切り替える好機。
- 合計サイズはデプロイあたり 64KBまで。
ステップ3:ステートフル依存を置き換える
ローカルファイル → Vercel Blob
EC2 のディスクに保存していたアップロードファイルや生成 PDF は、Blob へ。ユーザーアップロードは client upload(サーバーを経由せず、転送課金と 4.5MB 制限を回避)。
// 旧:fs.writeFileSync(path, buffer)
// 新:Vercel Blob(private で保存し、関数経由で配信)
import { put } from "@vercel/blob";
const blob = await put(`uploads/${id}.pdf`, buffer, {
access: "private",
addRandomSuffix: true,
});
DB 接続 → pooled 接続で枯渇を防ぐ
サーバーレスの並行性下では「1接続=1プロセス」の Postgres が枯渇します。pooled 接続(Neon の pooled エンドポイント等)へ。
// Neon の pooled 接続(サーバーレスでは必須級)
import { neon } from "@neondatabase/serverless";
const sql = neon(process.env.DATABASE_URL!); // pooled エンドポイント
接続枯渇の理屈は PgBouncer・接続プーリング を参照。VPC 内の専用 DB は、公開+認証エンドポイント化するか、Enterprise の Secure Compute を検討します。
cron / 常駐ワーカー → Cron Jobs / Workflows
// 旧:crontab や常駐デーモン → vercel.json の crons
{
"$schema": "https://openapi.vercel.sh/vercel.json",
"crons": [{ "path": "/api/cron/nightly", "schedule": "0 0 * * *" }]
}
Cron は CRON_SECRET で必ず保護し、長時間処理は Workflows/キューへ(Functions ガイド)。
ステップ4:プレビューで並走検証
DNS を切る前に、プレビュー(または Vercel の *.vercel.app 本番URL)で本番同等の検証を行います。
- **E2E(Playwright)**をプレビューURLに対して実行(E2E 設計)。
- 主要導線(ログイン・決済・アップロード・検索)を手動確認。
x-vercel-cacheでキャッシュが意図通りHIT/PRERENDERか確認(キャッシュ)。- 必要なら旧基盤と Vercel を一定期間並走させ、トラフィックの一部だけ Vercel に流して比較(DNS の加重や、フロントのフラグで段階移行)。
ステップ5:DNS カットオーバーとロールバック
いよいよ本番ドメインを切り替えます。
事前:DNSレコードのTTLを短く(例 300秒)しておく(切替・巻き戻しを速く)
↓
Vercelにカスタムドメインを追加し、指示どおりA/CNAMEレコードを設定
↓
本番デプロイをPromote(Rolling Releases併用なら段階配信)
↓
DNSを切り替え → 伝播を監視(dig / 監視ツール)
↓
問題があれば:DNSを旧基盤に戻す(即ロールバック)
or Vercel側はInstant Rollbackで前デプロイへ
- TTL を事前に短縮しておくと、切替も巻き戻しも速い。
- Vercel 側の不具合は Instant Rollback で即前デプロイへ。基盤ごと戻すなら DNS を戻す。
- Rolling Releases + Skew Protection を使えば、本番でも段階的に Vercel デプロイを広げられる(デプロイ)。
ステップ6:移行後の最適化
移行は「動いた」がゴールではありません。
- キャッシュ設計:旧基盤で SSR だったページを ISR/CDN キャッシュへ。
x-vercel-cacheでHITを実測(キャッシュ)。 - コスト:Active CPU 課金前提で、重い CPU 処理を分離、メモリ/
maxDurationを用途に合わせる(コスト)。 - セキュリティ:WAF/BotID で入口を守り、OIDC 鍵レスへ移行(Firewall)。
- 可観測性:Observability で関数・エラー率・CWV を監視(可観測性)。
移行チェックリスト
- サーバー前提の依存(ファイル/常駐/長時間/VPC内DB)を棚卸し・置き換え設計
- 環境変数を3環境に整理、
NEXT_PUBLIC_に機密なし、変更は新デプロイのみ反映を理解 - DB は pooled 接続、ローカルファイルは Blob、cron は Cron Jobs
- プレビューで E2E・主要導線・
x-vercel-cacheを検証 - DNS の TTL を事前短縮、カスタムドメイン設定
- カットオーバー後の監視と、DNS/Instant Rollback の戻し手順を用意
- 移行後にキャッシュ・コスト・セキュリティ・可観測性を最適化
まとめ
Vercel への移行は、**「DNS を最後に切る」「ステートフル依存を先に置き換える」**の2点を守れば、無停止で安全に進められます。
- 可否を正直に見極める(サーバー前提の依存が鍵)
- プレビューで並走検証してから DNS を切る
- ファイル→Blob、DB→pooled、cron→Cron Jobs、長時間→Workflows
- TTL 短縮 → Promote → DNS 切替 → 監視 → 戻せる構成
- 移行後にキャッシュ・コスト・セキュリティ・可観測性を仕上げる
移行可否の見極めから、ステートフル依存の再設計、無停止カットオーバー、移行後のコスト最適化まで、案件として伴走します。
本記事は Vercel 公式ドキュメント(環境変数・Blob・Cron・ドメイン、2026年6月時点)に基づきます。仕様は更新されるため、本番採用時は公式で最新値を確認してください。