Next.jsをバージョン9から本番環境で実行してきました。その大部分の期間、Vercelは明らかな選択肢でした — デプロイして、忘れて、先に進む。しかし2024年のどこかで、請求書が自動車ローンのように見え始めました。マーケティングサイトのホスティング費用が実際のクラウドインフラストラクチャのコストを上回る場合、何かが壊れています。そこでOpenNextの調査を始めました。過去1年間に3つの本番アプリをVercelから移行した後、意見を持っています。

これは「Vercelは悪い」という記事ではありません。Vercelは本当に優れています。しかし、もはや唯一の選択肢ではなく、多くのチームにとって、それは正しい選択肢ではありません。OpenNextを使用してNext.jsを自分でホストすることについて学んだことすべてをご紹介します — 良い点、悪い点、そして驚くほど手頃な価格。

目次

OpenNext: Self-Host Next.js on AWS, Cloudflare, or VPS Without Vercel

OpenNextとは何か、なぜ存在するのか

Next.jsはVercelで実行するために設計されました。これは陰謀ではなく、アーキテクチャです。ISR(増分静的再生成)、ミドルウェア、画像最適化、サーバーアクションなどの機能にはすべて、ベイクインされたVercel固有の実装があります。ランダムサーバーでnext startを実行しようとすると、Next.jsが実行できることのサブセットしか取得できません。

OpenNextは、Next.jsのビルド出力を取得し、他のプラットフォームで機能するデプロイメントパッケージに変換するオープンソースアダプターです。これはAWS Lambdaに焦点を当てたSST コミュニティプロジェクトとして始まりましたが、v3(2025年の現在のメジャーバージョン)の時点では、Cloudflare Workers、従来のNode.jsサーバーなどを含む複数のデプロイメントターゲットをサポートしています。

OpenNextが実際に処理することは以下の通りです:

  • ISRと再検証 — Vercelが内部インフラストラクチャで実装するタグベースの再検証システム? OpenNextはAWSではDynamoDB + SQSを使用して、またはCloudflareではKVストアを使用してこれを再作成します。
  • 画像最適化 — Next.jsの<Image>コンポーネントは最適化APIに依存しています。OpenNextはSharpベースのオプティマイザーをパッケージ化するか、プラットフォーム固有のソリューションにルーティングします。
  • ミドルウェア — Vercelではエッジで実行されます。OpenNextはこれをCloudFront Functions、Cloudflare Workers、またはVPSで実行中にマップします。
  • サーバーアクション — 完全なサポートで、適切なサーバー関数でルーティングされます。
  • ストリーミングと部分的な事前レンダリング — OpenNext v3.xでサポートが大幅に成熟しました。

OpenNextは何ではない

ホスティングプラットフォームではありません。CDNではありません。ビルドアダプターです — Next.jsの出力とインフラストラクチャ間の変換レイヤーです。実際にどこかでそれを実行する必要があります。

2025-2026年の自己ホスティングの状況

これを最初に調べ始めてから、エコシステムは爆発しました。状況は以下の通りです:

プラットフォーム OpenNextのサポート 成熟度 最適な用途
AWS(SST経由) ファーストクラス 本番環境対応 AWSに既にいるチーム
Cloudflare Workers 公式アダプター 安定(いくつかのエッジケース) エッジファースト アプリ、コスト最適化
Docker/VPS コミュニティ + 公式 安定 シンプルなデプロイメント、既存のインフラ
Kubernetes コミュニティHelmチャート 成熟段階 エンタープライズ、既存のK8sクラスタ
Netlify ビルトイン(独自のアダプター) 本番環境対応 Netlifyコミット済みチーム
Google Cloud Run コミュニティ 実験的 GCPショップ

私が個人的にテストし、保証できる2つのパスは、AWS経由のSSTとVPS上のDockerです。Cloudflareは毎月改善されている興味深い新しい来客です。

デプロイメントターゲット: SSTを使用したAWS

これが黄金のパスです。SST(Serverless Stack)はOpenNextで駆動されるビルトインのNext.jsサポートを備えており、最も多くのエンジニアリングの努力が費やされている場所です。

アーキテクチャの概要

SST経由でNext.jsをAWSにデプロイすると、次のものが作成されます:

  • CloudFrontディストリビューション — CDN、静的アセットとルーティングを処理します
  • Lambda関数 — サーバーサイドレンダリング、APIルート、サーバーアクション
  • S3バケット — 静的アセット、事前レンダリングされたページ、ISRキャッシュ
  • DynamoDBテーブル — ISRタグマッピング再検証用
  • SQSキュー — 非同期再検証処理
  • CloudFront FunctionまたはLambda@Edge — ミドルウェア実行

多くのように聞こえます。それです。しかし、SSTはそのすべてを約20行の設定に抽象化します。

SST設定

本番プロジェクトの実際のsst.config.tsを以下に示します:

/// <reference path="./.sst/platform/config.d.ts" />

export default $config({
  app(input) {
    return {
      name: "my-nextjs-app",
      removal: input.stage === "production" ? "retain" : "remove",
      home: "aws",
      providers: {
        aws: {
          region: "us-east-1",
        },
      },
    };
  },
  async run() {
    const site = new sst.aws.Nextjs("Site", {
      domain: {
        name: "myapp.com",
        dns: sst.aws.dns(),
      },
      warm: 5, // keep 5 Lambda instances warm
      memory: "1024 MB",
      environment: {
        DATABASE_URL: process.env.DATABASE_URL!,
        NEXT_PUBLIC_API_URL: "https://api.myapp.com",
      },
    });

    return {
      url: site.url,
    };
  },
});

その後デプロイ:

npx sst deploy --stage production

最初のデプロイメントには8〜12分かかります(CloudFrontディストリビューション伝播)。その後のデプロイメントは2〜4分です。

Lambda の検討事項

Lambdaベースのホスティングの最大の落とし穴はコールドスタートです。Next.jsサーバー関数は小さくありません — 依存関係に応じて20〜80MBのバンドルを見ています。コールドスタートは800msから3秒の範囲です。

私が使用した軽減策:

  1. プロビジョンされた同時実行性 — SSTのwarmパラメーターはインスタンスをホットに保ちます。1GBの関数の5つのインスタンスを保温するコストは月額約$15です。
  2. より小さなバンドル — サーバー側の依存関係を監査します。サーバー側でlodashのみインポートし、lodash/getが必要でしたプロジェクトを見つけました。バンドルは68MBから31MBに減少しました。
  3. 地域別デプロイメント — SRRが絶対に必要でない限り、Lambda@Edgeを使用しないでください。CloudFrontキャッシングを備えた単一地域のLambdaは、アプリの95%に適しています。

OpenNext: Self-Host Next.js on AWS, Cloudflare, or VPS Without Vercel - architecture

デプロイメントターゲット: Cloudflare Workers

Cloudflareは真摯に取り組んでいます。彼らのWorkers runtimeは十分なNode.js APIをサポートするようになったため、Next.jsは実際にそこで実行でき、OpenNext Cloudflareアダプターはかなり安定しました。

OpenNext Cloudflareでのセットアップ

npm install @opennext/cloudflare

wrangler.tomlに追加:

name = "my-nextjs-app"
main = ".open-next/worker.js"
compatibility_date = "2025-01-01"
compatibility_flags = ["nodejs_compat_v2"]

[assets]
directory = ".open-next/assets"
binding = "ASSETS"

[[kv_namespaces]]
binding = "NEXT_CACHE_KV"
id = "your-kv-namespace-id"

ビルドしてデプロイ:

npx @opennext/cloudflare build
npx wrangler deploy

Cloudflareのトレードオフ

メリット:

  • コールドスタートなし — Workers は5ms以内にグローバルに回転します
  • グローバルエッジがデフォルト — SSRは300以上の場所で実行されます
  • 不当な価格設定 — 有料プランで1000万リクエストあたり月額$5

デメリット:

  • メモリ制限 — 無料では128MB、有料では256MB。大きなNext.jsアプリがこれに当たることができます。
  • CPU時間制限 — 有料プランで30秒。重いSSRページは問題になる可能性があります。
  • Node.js互換性ギャップ — ほとんどの事は機能しますが、sharpのようなネイティブNode.jsモジュールを直接使用している場合は、回避策が必要になります。Cloudflare Imagesは代わりに最適化を処理できます。
  • 一部のNext.js機能はサポートされていません — 2025年初頭の時点では、部分的な事前レンダリングサポートはCloudflareではまだ実験的です。

コンテンツが豊富なサイトとマーケティングページの場合、Cloudflare Workersは非常に魅力的です。複雑なWebアプリケーションで大量のサーバー側ロジックがある場合、AWSまたはDockerの方をお勧めします。

デプロイメントターゲット: DockerのあるVPS

時々、あなたはただサーバーが必要です。Lambda関数なし、エッジランタイムなし、47サービスアーキテクチャ図なし。コードを実行するボックス。私はそれを尊重します。

Dockerfile

以下は、私が使用している本番Dockerfileです。マルチステージで、最適化されていて、実際に機能します:

# Stage 1: Dependencies
FROM node:20-alpine AS deps
RUN apk add --no-cache libc6-compat
WORKDIR /app
COPY package.json pnpm-lock.yaml ./
RUN corepack enable pnpm && pnpm install --frozen-lockfile

# Stage 2: Build
FROM node:20-alpine AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .

ENV NEXT_TELEMETRY_DISABLED=1
ENV NODE_ENV=production

RUN corepack enable pnpm && pnpm build

# Stage 3: Production
FROM node:20-alpine AS runner
WORKDIR /app

ENV NODE_ENV=production
ENV NEXT_TELEMETRY_DISABLED=1

RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs

COPY --from=builder /app/public ./public
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static

USER nextjs

EXPOSE 3000
ENV PORT=3000
ENV HOSTNAME="0.0.0.0"

CMD ["node", "server.js"]

重要:next.config.jsoutput: 'standalone'が必要です:

/** @type {import('next').NextConfig} */
const nextConfig = {
  output: 'standalone',
};

module.exports = nextConfig;

VPS推奨事項

このセットアップを複数のプロバイダーで実行しました:

プロバイダー スペック 月額料金 注記
Hetzner CAX21 4 vCPU ARM、8GB RAM €7.49(約$8) 最高の価値、EUデータセンター
DigitalOcean Droplet 2 vCPU、4GB RAM $24 良いUS カバレッジ
Fly.io(マシン) 2 vCPU、4GB RAM 約$30 自動スケーリング、グローバルリージョン
Railway 使用量ベース $5-50 最も簡単なセットアップ、Vercel風DX
AWS EC2 t4g.medium 2 vCPU、4GB RAM 約$25 すでにAWS上

ストレートフォワードなDockerデプロイメントの場合、Hetznerはばかげた価値があります。€7.49のHetzner ARMインスタンスでCloudflareの無料CDN層の背後にある月間2M以上のページビューを提供するNext.jsアプリを実行します。サーバーはほとんど問題を起こしません。

Docker/VPSで失うもの

VPS上のnext startがVercelまたはSST設定と比較して何を与えていないかについて正直に言いましょう:

  • ISR再検証は基本的です — ファイルシステムキャッシュのみ。複数のインスタンス間の分散キャッシュなし。単一サーバーを実行している場合、これは問題ありません。マルチサーバー?Redisまたはシェアドキャッシュレイヤーが必要です。
  • エッジミドルウェアなし — ミドルウェアはインプロセスで実行されます。これはほとんどのユースケースにとって完全に問題ありません。
  • 画像最適化 — Sharpを介して機能しますが、単一のオリジンから最適化された画像を提供しています。CloudflareまたはCDNの前に置きます。
  • アトミックなデプロイメントなし — ゼロダウンタイムデプロイメントを自分で処理する必要があります(ヘルスチェック付きDocker Compose、またはCaddy/Traefikのようなリバースプロキシ)。

ほとんどのアプリ、特にヘッドレスCMS開発の作業を通じて行うヘッドレスCMSビルドについては、CDNの背後にある単一のVPSは完全に適切です。

コスト比較: VercelとセルフホスティングVS

お金について話しましょう。これは、ISR、画像最適化、および適度なサーバー側レンダリングを行い、約500万リクエスト/月を実行しているNext.jsアプリからのリアルな請求データに基づいています。

コスト要素 Vercel Pro Vercel Enterprise AWS/SST Cloudflare Hetzner VPS
ベースプラットフォーム ユーザーあたり月額$20 カスタム(月額約$3k以上) $0 月額$5 €7.49/月
コンピュート/リクエスト 月額$150-400 含まれています 月額$40-80 月額$0-15 含まれています
帯域幅(100GB) 含まれています 含まれています 月額$8.50(CloudFront) 含まれています 含まれています
画像最適化 月額$50-200 含まれています 月額$5-15(Lambda) 月額$5(CF Images) 含まれています(Sharp)
ISR/キャッシュ 含まれています 含まれています 月額$2-5(DynamoDB) 月額$0-5(KV) $0
推定合計 月額$300-700 月額$3,000以上 月額$55-110 月額$10-25 月額$8-15

これらのVercelの数字は仮説ではありません。請求書を見たことがあります。Pro層での座席ごとの価格設定、機能実行オーバーヘッド、および帯域幅料金は、5人以上のチームではすぐに追加されます。

AWS/SST数値は適度なトラフィックとプロビジョンされた同時実行性を想定しています。Cloudflareの価格は本当に狂っています — 何か異国的でない限り、そこで本当のお金を費やすことは難しいです。

Vercelを去る時

去るのは、あなただけだからではなく、去りなさい。去るのは、あなたが去るべきだからです。以下は私のフレームワークです:

Vercelに留まる場合:

  • チームが小さい(1-3人の開発者)で、開発者の時間が最も高い資源です
  • Vercelで月額100ドル未満を費やしている
  • インフラストラクチャー作業を楽しむ人がいない
  • 迅速に反復しており、すべてのPRの即座なプレビューが必要
  • Vercel分析、Speed Insights、またはVercel AI SDKの統合などのVercel固有の機能を使用しています

Vercelを去る場合:

  • 月額請求書が$500を超えて増加している
  • コンプライアンス(GDPR、データレジデンシー)のため、特定の地域のインフラストラクチャが必要です
  • すでに大量のAWS/GCP/Cloudflareインフラストラクチャを実行しています
  • Serverlessのコールドスタートはユースケースで許容できません
  • Vercelの関数サイズ制限または実行時制限に達しました
  • Vercel Enterprise価格で、契約更新がちょうどやって来ました

真剣に去ることを検討してください:

  • Vercel Enterprise価格で、契約更新がちょうどやって来ました
  • アプリはほぼ静的/ISRで、動的SSRの価格を支払っています
  • フロントエンドをバックエンドと同じインフラストラクチャで実行したい

移行プレイブック

私はこれを3回やったことがあります。以下は私が従うプロセスで、苦い経験を通じて洗練されました。

ステップ1:Next.js機能を監査する

何かに触れる前に、実際に使用するNext.js機能をカタログ化します:

# Find middleware
find . -name "middleware.ts" -o -name "middleware.js"

# Find API routes
find ./app -name "route.ts" -o -name "route.js" | head -20

# Check for ISR
grep -r "revalidate" ./app --include="*.ts" --include="*.tsx" | head -20

# Check for server actions
grep -r "use server" ./app --include="*.ts" --include="*.tsx" | head -20

# Check next.config for special features
cat next.config.js

ステップ2:ターゲットを選択する

監査に基づいて:

  • 重いISR +ミドルウェア+画像最適化→AWS/SST
  • シンプルなSSR +コンテンツサイト→CloudflareまたはVPS
  • すでにDocker/K8sインフラストラクチャを持っている→VPS/Docker
  • 金曜日までにそれをやる必要がある→Railway またはFly.ioのDocker

Next.jsまたはAstroで構築している場合、ターゲットプラットフォームの選択はアーキテクチャの決定に大きく影響します。

ステップ3: CI/CDをセットアップする

VercelのCI/CDは本当に素晴らしいです。あなたはそれを逃します。GitHub Actionsで複製します:

# .github/workflows/deploy.yml
name: Deploy
on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: pnpm/action-setup@v4
        with:
          version: 9

      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: 'pnpm'

      - run: pnpm install --frozen-lockfile
      - run: pnpm build
      - run: pnpm test

      # For SST:
      - run: npx sst deploy --stage production
        env:
          AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}

      # For Docker/VPS (alternative):
      # - run: docker build -t myapp .
      # - run: docker push registry.example.com/myapp:latest
      # - run: ssh deploy@server 'cd /app && docker compose pull && docker compose up -d'

ステップ4:プレビューデプロイメント

これは、Vercelで逃したい1つのことです。SSTの場合、ステージを使用します:

# In your PR CI workflow
npx sst deploy --stage pr-${{ github.event.pull_request.number }}

Dockerの場合、Coolify(自己ホスト)またはRailwayのようなツールはプレビューデプロイメントをうまく処理します。

ステップ5:DNSカットオーバー

実際の移行の瞬間。常にお勧めします:

  1. 新しいインフラストラクチャをVercelと並行してデプロイします
  2. ステージングドメインで徹底的にテストします
  3. デプロイの1日前にDNS TTLを60秒に低減します
  4. トラフィックが低い時間帯にDNS をカットします
  5. Vercelデプロイメントをフォールバックとして48時間実行し続けます
  6. エラー率、TTFB、およびCore Web Vitalsを密接に監視します

ステップ6:Vercelを取り壊す

自信がある場合(少なくとも1週間待つ)、Vercelのサブスクリプションをキャンセルしてプロジェクトを削除します。ゾンビプロジェクトが料金を掛けるのを残さないでください。

一般的な落とし穴とそれを避ける方法

環境変数が消えます。 Next.jsにはNEXT_PUBLIC_接頭辞付きvar(ビルド時にバンドルされた)とサーバー専用var(実行時に利用可能)があります。Vercelでは、この区別はやや曖昧です。自己ホスト上では、それは厳密です。すべてのNEXT_PUBLIC_varがCI内の構築時に利用可能であることを確認します。

ISRキャッシュは保持されていません。 Dockerでは、.next/cacheディレクトリは永続ボリューム上にある必要があります。そうしないと、容器が再起動するたびに、キャッシュされたページが失われます。

# docker-compose.yml
services:
  web:
    build: .
    ports:
      - "3000:3000"
    volumes:
      - next-cache:/app/.next/cache

volumes:
  next-cache:

Sharp インストールエラーが失敗します。 sharp画像最適化ライブラリには、プラットフォーム固有のバイナリが必要です。Dockerでは、ランタイムと同じアーキテクチャ内で依存関係をインストールしていることを確認します。上記のDockerfileは、同じベースイメージを使用したマルチステージビルドでこれを処理します。

ミドルウェアの動作の違い。 Vercelはミドルウェアをエッジネットワークで実行します。AWS/SSTでは、CloudFront関数として実行されます(10ms実行制限、2MBサイズ)。複雑なミドルウェアは、サーバー関数に移動する必要があるかもしれません。これらの制限により認証ミドルウェアを再因数分解する必要がありました。

ヘッダーと書き換えが不足しています。 vercel.jsonにヘッダー、リダイレクト、または書き換えを依存していた場合は、これらをnext.config.jsまたはCDN/リバースプロキシ構成に移動する必要があります。

これのいずれかが圧倒的に感じる場合、それはまさにSocial Animalで処理するインフラストラクチャ作業です。価格設定をチェックするか、お問い合わせください — 私たちはこれらの移行を何度も行うために改良されたプロセスを持っています。

FAQ

OpenNextは2025年で本番環境対応ですか?

はい。OpenNext v3.xは数千の企業の本番ワークロードを実行しています。SST/AWSパスは最も戦闘テストされており、Cloudflareのサポートが近いです。Google CloudやむきMurkubernetesサポートはまだ成熟していないと言いませんが、AWSとCloudflareは固いです。

OpenNextはNext.js App RouterとServer Componentsをサポートしていますか?

完全なサポート。App Router、Server Components、Server Actions、streaming、およびSuspenseはすべて機能します。OpenNext チームはNext.jsリリースを密接に追跡しており、ただし通常はNext.jsメジャーバージョン後、OpenNextがキャッチアップするまで1〜3週間の遅れがあります。

Vercelを離れることで実際にどのくらい節約できますか?

使用パターンに大きく依存します。5人の開発者がチームを実行している中程度のトラフィックアプリの場合、チームがVercel Proの月額600〜800ドルからAWS/SSTで月額30〜80ドル、またはVPS で月額20ドル未満に移動するのを見ました。節約は現実ですが、追加のメンテナンス負担も同様です。

Vercelなしで ISR(増分静的再生成)を使用できますか?

完全に。AWS/SSTでは、ISRはタグキャッシュ用のDynamoDBとpython非同期再検証用のSQSを使用します — これは完全に機能的であり、revalidateTag()revalidatePath()経由の要求時再検証を含みます。VPS上では、ISRはファイルシステムキャッシュで動作します。これは単一サーバーのデプロイメントでは問題ありません。

Vercelのプレビューデプロイメントについてはどうですか?それらを複製できますか?

あなたは経験の80%を取得できます。SSTはステージベースのデプロイメントをサポートしているため、各PRは独自のスタックを取得できます。Coolifyおよび同様のツールは、Dockerベースのセットアップのプレビューデプロイメントを提供します。あなたが簡単に複製しないことは、Vercelのビジュアルコメントシステムとデプロイメント状態のタイトなGithub統合です。ほとんどのチームはトレードオフが許容可能であることを発見しています。

ヘッドレスCMSサイト用にCloudflare またはAWSでOpenNextを使用する必要がありますか?

コンテンツが豊富なヘッドレスCMSサイト(Sanity、Contentful、Storyblok)については、Cloudflare Workersは優れた選択肢です。これらのサイトはISR対応の傾向があり、比較的軽いサーバー側ロジックを持っています — Cloudflareの価格モデルに完璧です。Cloudflareがまだサポートしていない機能が必要な場合、またはAWSエコシステムに深く含まれている場合は、AWSを使用することのみをお勧めします。

自ホストするNext.jsは、自ホストするAstro またはRemixよりも難しいですか?

正直に言うと、はい。Next.jsは、ISR、ミドルウェア、画像最適化、部分的な事前レンダリングなどの機能があるため、任意のフレームワークの最も複雑なビルド出力です。Astro とRemixは非常にシンプルなデプロイメント物語を持っています。自己ホスティングが優先事項である新しいプロジェクトを開始している場合は、Astroを検討してください — ホストするのが劇的に簡単です。しかし、あなたがすでにNext.jsに何もない場合、OpenNextは移行の実用性を増す。

OpenNextがメンテナンスされなくなった場合はどうなりますか?

OpenNextはSST が支持し、スポンサーを持つ大量のアクティブコミュニティがあります。とはいえ、これはあらゆるオープンソース依存関係の正当な懸念です。軽減策は、Docker/スタンドアロンアプローチ(next start)がOpenNextなしで機能することです — より高度な機能(ISRタグ再検証とエッジミドルウェア)の一部を失うだけです。これは崖ではなく、優雅な劣化です。