メインコンテンツへスキップ
友田 陽大
Vercel 本番運用
Vercel
Fluid Compute
Python
TypeScript
サーバーレス
アーキテクチャ設計
可観測性

Vercel でバックエンドを動かす:Express・Hono・FastAPI・NestJS をゼロ設定で本番運用する

Vercelはフロント専用ではなくフルコンピュート基盤。Express・Hono・NestJS(Node.js 24)やFastAPI(Python)をゼロ設定で動かす方法を公式準拠で解説。server.listenによるNodeサーバー検出、fetch Web Handler、apiディレクトリ、Fluid Computeでの並行性とグローバル状態の注意、フロントとの同居(Services)までを実コードで。

公開日
読了時間
7分
著者
友田 陽大
シェア

「Vercel はフロントエンドを置く場所で、バックエンドは別のサーバーが要るんでしょう?」——これは2026年には明確な誤解です。Vercel は Express・Hono・NestJS(Node.js)や FastAPI(Python)といったバックエンドフレームワークを、ほぼゼロ設定でそのまま動かすフルコンピュート基盤です。

この記事は Node.js ランタイムの公式仕様に忠実に、Vercel でバックエンドを本番運用する方法をまとめます。全体像は Vercel 本番運用ガイド、関数の詳細は Functions・Fluid Compute ガイド を参照してください。


3つのデプロイ形

Vercel でバックエンドを動かす形は3つあります。

書き方向く場面
Node.js サーバー検出server.tsserver.listen()既存の Express/Hono/Fastify アプリ「丸ごと」
fetch Web Handlerapi/*.tsexport default { fetch }軽量・Web 標準・関数単位
HTTP メソッド別 exportapi/*.tsexport function GET/POSTREST エンドポイント単位

① Node.js サーバーを丸ごと載せる

Vercel は、プロジェクトルートか src/server.{js,cjs,mjs,ts,cts,mts} を検出し、server.listen() の呼び出しを手がかりにHTTP サーバーを関数化します。listen() に渡すポートはローカル実行用で、本番では内部ポート経由でルーティングされます(公開ポートにはなりません)。

// server.ts — 標準の Node.js HTTP サーバー(Vercel が検出)
import { createServer } from "node:http";

const server = createServer((request, response) => {
  const url = new URL(request.url ?? "/", `http://${request.headers.host}`);
  if (request.method === "GET" && url.pathname === "/health") {
    response.writeHead(200, { "Content-Type": "application/json" });
    response.end(JSON.stringify({ status: "ok" }));
    return;
  }
  response.writeHead(200, { "Content-Type": "text/plain" });
  response.end("Hello from Node.js on Vercel");
});

// ローカル用ポート。Vercel はこの listen を検出してサーバーを捕捉する
server.listen(Number(process.env.PORT ?? 3000));

② Hono を載せる(fetch ハンドラと相性抜群)

Hono は Web 標準の fetch ハンドラなので、Vercel の Web Handler とそのまま噛み合います。

// api/index.ts — Hono を fetch Web Handler として
import { Hono } from "hono";

const app = new Hono();
app.get("/api/health", (c) => c.json({ status: "ok" }));
app.post("/api/echo", async (c) => c.json(await c.req.json()));

// Vercel は fetch エクスポートをそのまま関数として実行する
export default { fetch: app.fetch };

③ Express を載せる

Express は Node.js で最も使われるフレームワークで、Vercel に専用ガイドがあります。基本は server.listen() でサーバー検出に乗せるか、サーバーレス用アダプタでハンドラ化します。

// server.ts — Express を Node.js サーバー検出に乗せる
import express from "express";

const app = express();
app.use(express.json());
app.get("/api/health", (_req, res) => res.json({ status: "ok" }));

app.listen(Number(process.env.PORT ?? 3000)); // Vercel が検出

④ NestJS

NestJS は Express/Fastify をアダプタに持つので、bootstrap()listen() を呼ぶ標準構成がそのまま乗ります(重い初期化はコールドスタートに効くので注意)。

// server.ts
import { NestFactory } from "@nestjs/core";
import { AppModule } from "./app.module";

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(Number(process.env.PORT ?? 3000));
}
bootstrap();

⑤ FastAPI(Python)

Vercel は Python(3.13/3.14)も Fluid Compute で動かします。FastAPI を ASGI アプリとしてデプロイできます。

# api/index.py — FastAPI on Vercel(Python ランタイム)
from fastapi import FastAPI

app = FastAPI()

@app.get("/api/health")
def health():
    return {"status": "ok"}

FastAPI 本体の本番設計(非同期・Pydantic・DI)は FastAPI 本番ガイド を参照。


最大の注意:Fluid Compute のグローバル状態

どのフレームワークでも、Vercel(Fluid Compute)では1つのインスタンスが複数リクエストを並行処理します。だから、モジュールスコープにリクエスト固有の状態を置くと漏洩します。

// ❌ 危険:Express の app レベルやモジュールスコープに「現在のユーザー」を持つ
let currentUser; // 全リクエストで共有される

// ✅ 安全:リクエスト固有はハンドラ内のローカルに閉じる
app.get("/me", (req, res) => {
  const user = authenticate(req); // ローカル
  res.json(user);
});

// ✅ グローバルに置いてよいのは「リクエスト非依存」のものだけ
const pool = createPool(process.env.DATABASE_URL!); // 接続プール

これは「サーバーで1プロセス1リクエスト」に慣れた人ほど見落とします。詳細は Functions・Fluid Compute ガイド の「共有グローバル状態」を参照。


バックエンド設計の前提(制限)

Vercel でバックエンドを設計するときの前提(Functions 制限):

  • タイムアウト:既定300秒、Pro/Ent 最大800秒。長時間処理は Workflows/キューへ。
  • ボディ:リクエスト/レスポンス本文 4.5MB。大きなアップロードは Blob の client upload
  • メモリ/CPU:Pro/Ent 最大 4GB/2vCPU。
  • DB 接続:サーバーレスの並行性で枯渇しやすい → pooled 接続接続プーリング)。
  • 状態:ステートレスに。状態は外部(DB/Blob/Redis)へ。
  • コストActive CPU 課金(I/O 待ち非課金)。I/O 主体の API は効率的。

フロントとバックエンドの同居:Services

Next.js のフロントと Node.js サーバーを同一プロジェクトで併存させたい場合は、Services を使います。フロントは Next.js、API は別の Node.js サーバーとして、1つのプロジェクト内で動かせます。BFF パターン(フロント専用のバックエンド)をモノレポで組むのに向きます。

マイクロサービス的に分けるなら、フロント=Next.js プロジェクト、API=別プロジェクトに分離し、rewrites でつなぐ構成も有効です(vercel.ts のrewrite)。


いつ「Vercel でバックエンド」が向くか

向く向きにくい
REST/GraphQL/BFF・Webhook 受け常駐 WebSocket サーバー(SSE か外部基盤へ)
I/O 主体(DB/外部API/AI)数分超の重い CPU バッチ(Workflows へ)
Next.js と同居の API巨大モノリス(250MB バンドル超)
スパイクするトラフィック(自動スケール)VPC 内のみ・公開不可な専用DB(要 Secure Compute 等)

向かないものは「分離」で解けます——長時間は Workflows、常駐は外部基盤、巨大は機能分割。


本番チェックリスト(バックエンド on Vercel)

  • サーバー検出(server.listen())か Web Handler か、形を選択
  • グローバル状態にリクエスト固有データを置いていない
  • DB は pooled 接続、状態は外部ストアへ(ステートレス)
  • タイムアウト300秒・ボディ4.5MB を前提に設計、超える処理は分離
  • 重い初期化を避けコールドスタートを抑える
  • フロント同居は Services、分離は rewrites
  • Active CPU 課金前提でコスト設計、Observability で監視

まとめ

Vercel は「フロントを置く場所」ではなく、Express・Hono・NestJS・FastAPI をゼロ設定で動かすバックエンド基盤でもあります。

  1. 3つの形(サーバー検出 / fetch Handler / メソッド別)から選ぶ
  2. Fluid のグローバル状態に注意(リクエスト固有はローカルに)
  3. ステートレス・pooled 接続・4.5MB・300秒を前提に設計
  4. 長時間/常駐/巨大は分離で解く
  5. フロント同居は Services

Next.js フロント+Vercel バックエンドの一気通貫構成(BFF・API・Webhook)を、設計から本番運用まで承ります。

本記事は Node.js ランタイム / Functions 制限 公式ドキュメント(2026年6月時点)に基づきます。仕様は更新されるため、本番採用時は公式で最新値を確認してください。

友田

友田 陽大

経済産業大臣賞 受賞プロダクト開発者。TypeScript + Python + AWS で、SaaS・業界DX・ 実用レベルの生成AI(RAG)を、要件定義からインフラ・運用まで一人で完遂します。

この記事の実装を、案件として承ります

Vercel のアプリを、設計から本番運用・コスト最適化まで承ります

Fluid Compute を前提とした関数設計(グローバル状態の安全化・waitUntil・Cron)、4層キャッシュ(ISR/CDN/Runtime Cache/Cache Components)の設計、プレビュー/Promote/Instant Rollback/Rolling Releases の安全なデプロイ、Firewall/WAF/BotID の入口防御、Blob/Edge Config/Marketplace のストレージ選定、Active CPU 課金前提のコスト最適化まで。Next.js 製プロダクトを Vercel で本番運用してきた知見で、速く・安く・安全に伴走します。

プロジェクト単位(請負)・技術顧問のどちらにも対応可能です。まずは30分の無料技術相談から。

あわせて読みたい