CloudflareスタックでWeb開発 — Next.js+D1+Better Auth+Stripe+R2構成ガイド
Next.js・Cloudflare D1・Better Auth・Stripe・R2・Workersを組み合わせたCloudflareスタックの全体構成を丁寧に解説します。料金の目安やD1とSupabaseの比較、認証・決済の実装方法、デプロイまでの具体的な手順を開発者向けにわかりやすく紹介します。
Cloudflareスタックとは
本記事で解説するのは、クライアントとAPIをNext.js、データベースをCloudflare D1、認証をBetter Auth、決済をStripe、ストレージをCloudflare R2、ホスティングをCloudflare Workersで統一する「Cloudflareスタック」の構成です。個人開発や小〜中規模のSaaSを、最小限のインフラ管理とサーバーレスの料金モデルで立ち上げたい開発者に向いています。各レイヤーの役割、料金の目安、デプロイまでの手順を順に見ていきます。
全体アーキテクチャ
このスタックの中心は1つのCloudflare Workerです。Next.jsのApp RouterによるフロントエンドとRoute HandlerによるAPIエンドポイントが同じWorker上に同居し、Better Authの認証ロジックもRoute Handlerとしてこのアプリ内にマウントされます。データベース(Cloudflare D1)、オブジェクトストレージ(Cloudflare R2)、ページキャッシュ用のKVは、いずれもネットワークホップを挟まない「バインディング」経由でWorkerから直接呼び出されます。決済だけは外部のSaaSであるStripeが担い、サブスクリプションの作成・更新・キャンセルはBetter AuthのStripeプラグインが仲介し、StripeからのWebhookが/api/auth/stripe/webhookにコールバックされることで状態が同期されます。つまり「フロント・API・認証はWorker内で完結し、決済だけが外部から戻ってくる」という単純な形が全体像です。この『全部Cloudflareに寄せる』構成が実際にどこまで妥当かは、「Cloudflareだけに全部デプロイしろ」論争の検証記事でも論点を整理しているので参考にしてほしい。

クライアント&バックエンド: Next.js on Cloudflare Workers
Next.jsをCloudflare Workers上で動かす公式手段は、OpenNextのCloudflareアダプタ@opennextjs/cloudflareです。2026年2月に1.0がGAとなり、Next.js 16の全マイナー・パッチバージョンと、15・14系の最新マイナーバージョンをサポートしています(14系は2026年第1四半期でサポート終了予定)。アプリはEdge RuntimeではなくNode.jsランタイムで動作し、WorkersランタイムのNode.js APIをそのまま利用できます。有効化にはnodejs_compat互換フラグと、2024年9月23日以降のcompatibility_dateの指定が必要です。Workerのスクリプトサイズには上限があり、Freeプランは3MiB、Paidプランは10MiBまでとなっています。アダプタはページキャッシュにKVを、KVの25MiB値上限を超える静的アセットにはR2を自動的に使い分けます。フロントエンド(App Router/React Server Components)とAPI(Route Handler)を同じNext.jsアプリ=同じWorkerに同居させられるのがこの構成の大きな利点で、APIをHonoなど別フレームワークで分離する構成についてはHono × Cloudflare Workers のAPI構築ガイドで個別に扱っています。詳細な対応状況はOpenNext公式ドキュメントで随時更新されています。新規プロジェクトは次のコマンドで作成できます。
npm create cloudflare@latest my-app -- --framework=nextデプロイはnpx wrangler deploy(またはプロジェクトのdeployスクリプト)を実行するだけです。
データベース: Cloudflare D1
Cloudflare D1はSQLiteベースのサーバーレスデータベースです。Workersからは「バインディング」を通じて直接呼び出せるため、ネットワークホップが発生しません。読み取りはエッジに近い場所で処理され、書き込みはプライマリの1箇所に集約されます。ORMはDrizzle ORMやKysely(D1Dialect)から扱うのが一般的です。1データベースあたりのストレージ上限は10GBです。料金体系はFreeプランとWorkers Paidプランで大きく異なります。
| プラン | 行読み取り | 行書き込み | ストレージ | 超過単価・備考 |
|---|---|---|---|---|
| Free | 500万/日 | 10万/日 | 合計5GB | 上限到達でクエリがエラー(毎日UTC0:00リセット) |
| Workers Paid | 250億/月込み | 5,000万/月込み | 5GB込み | 読取$0.001/100万行・書込$1.00/100万行・容量$0.75/GB-月 |
データ転送料はかからず、実行時のみ課金される点も覚えておきたいポイントです。詳細な料金条件はCloudflare公式のD1料金ページにまとまっています。
D1 vs Supabase: どちらを選ぶか
Cloudflare D1としばしば比較されるのがSupabaseです。Supabaseは PostgreSQLのマネージドデータベースを中心に、認証・ストレージ・リアルタイム機能・Edge Functions・ベクトル検索までを束ねた「バックエンド基盤」で、特定リージョンのインスタンス(および必要に応じたリードレプリカ)で稼働します。一方D1はSQLiteセマンティクスの軽量データベースで、Workersネイティブに組み込まれ、読み取り中心の処理をグローバルに配信するシンプルなスキーマ運用に向いています。選定の目安は、「データベースが製品の中心にあり、JOINやRLS(行レベルセキュリティのポリシー)、拡張機能、リアルタイム購読が必要」ならSupabase、「読み取り中心でWorkers完結、小〜中規模でコストを最小化したい」ならD1、という整理になります。
| 観点 | Cloudflare D1 | Supabase |
|---|---|---|
| DBエンジン | SQLite | PostgreSQL |
| 配置 | Workersにバインディングで直結 | 特定リージョンのマネージドインスタンス |
| 付属機能 | KV・R2と組み合わせて構成 | 認証・ストレージ・リアルタイム・Edge Functions・ベクトル検索を標準搭載 |
| 向くケース | 読み取り中心・Workers完結・小〜中規模 | DBが中心・JOIN/RLS/拡張/リアルタイムが必要 |
| 上限 | 1DBあたり10GB | リージョン単位のインスタンススペックに依存 |
認証: Better Auth
Better AuthはTypeScript製のセルフホスト認証フレームワークです。D1向けの専用アダプタは用意されていないため、Drizzleアダプタ、またはKyselyのD1Dialect経由で接続します。
drizzleAdapter(db, { provider: "sqlite" })プラグイン方式を採っており、管理者機能・APIキー・二要素認証・組織/RBACなど15以上のプラグインが用意されています。1.4〜1.5系ではOAuth 2.1プロバイダ、ステートレスセッション、JWT鍵ローテーション、SCIM、Stripeサブスクリプション制御の強化などが加わりました。HonoやNext.jsのRoute Handlerいずれにもマウントでき、コミュニティ製のbetter-auth-cloudflareパッケージも存在します。
決済: Stripe
決済にはStripeを、Better AuthのStripeプラグイン経由で組み込みます。導入は次のコマンドから始めます。
npm install @better-auth/stripe stripe@^22.0.0このプラグインを使うと、サインアップ時のStripe顧客自動作成、サブスクリプションのプラン/価格管理、作成・更新・キャンセル、署名検証付きWebhook処理、トライアルや複数プラン、チーム(シート)課金までをBetter Auth側で扱えます。セットアップではstripeClientとstripeWebhookSecretを渡してサーバー側にプラグインを登録し、クライアント側にはstripeClientプラグインを追加、npx auth migrateでテーブルを作成したうえで、Stripeダッシュボードにhttps://<domain>/api/auth/stripe/webhookをWebhook URLとして登録します。詳細なプラグイン仕様はBetter Auth公式のStripeプラグインドキュメントにまとまっています。
ストレージ: Cloudflare R2
Cloudflare R2はS3互換のオブジェクトストレージで、最大の特徴はエグレス(下り転送)が無料である点です。無料枠はストレージ10GB、Class A操作(書き込み・一覧)100万回/月、Class B操作(読み取り)1,000万回/月までとなっています。超過分はストレージ$0.015/GB-月、Class A $4.50/100万回、Class B $0.36/100万回で課金されます。Workersからはバインディングで直接読み書きでき、既存のS3対応ツールを使いたい場合はS3互換APIも利用できます。
ホスティング: Cloudflare Workers
アプリ全体のホスティング基盤となるCloudflare Workersにも、Freeプランと Paidプランがあります。データ転送・帯域幅の課金はなく、静的アセットの配信も無料かつ無制限です。
| プラン | リクエスト | CPU時間 | 料金 |
|---|---|---|---|
| Free | 10万/日 | 1呼び出しあたり10ms | 無料 |
| Paid | 1,000万/月込み(超過$0.30/100万) | 3,000万CPU-ms/月込み(超過$0.02/100万CPU-ms) | $5/月〜 |
1回の呼び出しで実行できる最大時間は5分です。
月額コストの目安
- 個人開発・検証段階: Workers Free・D1 Free・R2無料枠の範囲内であれば、実質無料で運用できる
- 小規模SaaSが本番稼働する段階: Workers Paidの$5/月〜を土台に、D1・R2の従量課金が上乗せされる($5〜+従量、という構成になる)
- 決済まわりのStripe手数料は別建てで、取引ごとの手数料がかかる
デプロイまでの流れ
- npm create cloudflare@latest でNext.jsプロジェクトを作成する
- wranglerの設定にd1_databases・r2_bucketsなどのバインディングを追加する
- D1に対してマイグレーションを実行し、スキーマを反映する
- npx wrangler deployでWorkerとしてデプロイする
向き不向き
向いているのは、個人開発やMVPの立ち上げ、読み取り中心のワークロード、インフラコストを最小限に抑えたいケースです。一方、複雑なJOINを伴う重いリレーショナル処理、RLS(行レベルセキュリティ)が必須の要件、1データベースで10GBを超える規模、5分を超える長時間バッチ処理などには向きません。
よくある質問
無料で始められますか?
Workers Free・D1 Free・R2の無料枠を組み合わせれば、個人開発や検証段階では実質無料で運用できます。ただしFreeプランのD1は1日あたりの行読み取り500万・行書き込み10万という上限があり、超えるとクエリがエラーになる点には注意が必要です。
SupabaseとD1、どちらを選ぶべきですか?
データベースが製品の中心にあり、JOINやRLS、拡張機能、リアルタイム機能が必要ならSupabaseが向いています。読み取り中心の処理をWorkers内で完結させ、小〜中規模でコストを最小化したいならD1が向いています。
Vercelにデプロイするのと何が違いますか?
CloudflareのWorkersはスクリプトサイズに上限(Free 3MiB/Paid 10MiB)があり、Node.js APIを使うにはnodejs_compat互換フラグの指定が必要です。その代わりデータ転送・帯域の課金がなく、Paidプランは$5/月からの定額で始められます。
日本からのレイテンシはどうなりますか?
D1の読み取りはエッジに近い場所で処理されるため、日本からのアクセスでも読み取りは高速になりやすい構成です。一方、書き込みはプライマリの1箇所に集約されるため、プライマリの所在地によっては書き込み時のレイテンシが発生し得ます。
まとめ
Next.js・D1・Better Auth・Stripe・R2・Workersを組み合わせるCloudflareスタックは、1つのWorkerにフロント・API・認証を同居させ、DBとストレージをバインディングで直結し、決済だけを外部のStripeに委ねるというシンプルな全体像を持っています。料金は使った分だけの従量課金が基本で、個人開発から小規模SaaSまでインフラ管理の手間を抑えながら立ち上げられる構成といえます。
この記事に関連する無料ツール(登録不要・その場で結果)
お気軽にご相談ください
お問い合わせ