
Next.jsなのにVercelを使わなかった理由。R2起点で考えた個人開発の技術構成

TL;DR
Next.js個人開発の定石であるVercelを使わず、
あえてCloudflare(Pages/Workers + R2 + Hyperdrive経由Supabase)
一本の構成にした起点は「画像ストレージをどこに置くか」。
掲示板サイトで画像を大量に扱うため、
エグレス無料のR2を活かす方向から
フロントもDBもCloudflareに寄せたDBはSupabase(素のPostgres)を採用。
Cloudflare D1は将来Postgres移行の
身動きの取りやすさを優先して見送ったコストは無料枠中心。
現在の会員規模(50人前後)なら
数万〜十万枚オーダーの投稿画像まで
無料枠+わずかな追加費用で捌ける試算フルバイブコーディング(コードは1行も
書かず、Claude Codeに実装させた)で作り、
権限設計・画像圧縮・スマホUIなど
地味なバグを後から潰していった実録
想定読者
Next.js個人開発でVercel以外の
ホスティング選択肢を検討している人Cloudflare(Pages/Workers/R2/Hyperdrive)
を使った構成に興味がある人画像を大量に扱うサービスの
ストレージ設計で悩んでいる人バイブコーディング(AIにコードを
書かせる開発)が実際どこまで
通用するのか、単純に気になる人個人開発でどこに地雷が埋まっているか、
他人の実例で先回りして知りたい人
はじめに
先日、「私設タラヲガールズ学園」という
ファンコミュニティの公式サイトを
個人開発した経緯を記事にした。
▼ 前編はこちら ▼
今回はその続編、技術寄りの話。
「自動化技術で売っている Marie」
をやっている以上、一度ちゃんとした
個人開発の話も書いておきたかった。
どんな構成を選んで、なぜそうしたのか、
そしてどんな地雷を踏んで直したのか。
それを書いていく。
先に断っておくと、
今回はフルバイブコーディング。
設計判断や動作確認は自分でやってるけど、
コードは1行も自分の手で書いていない。
思いついてから2日後の7/31には、
ログイン機能を含む
最初のプロトタイプが動いていた。
そこから挙がった改善点を直して、
ふらちゃんに渡し直したのが8/10。
このスピード感は、Claude Code に
全部書いてもらっていたからこそ出せたもの。

技術構成
今回、個人開発・Next.js という組み合わせなら
定番のはずの Vercel を、あえて使っていない。
Vercel は Next.js 自体を作っている会社が
提供するホスティングサービスで、
「とりあえず Vercel」が
定石になっているのには理由がある。
Vercel の主な特長
git push すれば自動デプロイ。
CI 設定を自分で組む必要がないブランチ・PR ごとに
プレビュー URL が自動発行される本番/プレビュー/開発の環境分離が標準機能
Next.js との組み合わせ実績が圧倒的に長く、
つまずいたときの先行知見も一番豊富
(記事・Q&A・公式ドキュメントなど)個人開発でも十分な無料枠がある
Developer Experience の高さは折り紙付き。
それでも、今回はあえてここを外した。

代わりに採用したのは、こんな構成。
フロントエンド:
Next.js(App Router)ホスティング:
Cloudflare Pages/Workers
(@opennextjs/cloudflare 経由でデプロイ)画像配信:
Cloudflare R2
(S3 互換、CDN 配信込みでエグレス無料)データベース:
Supabase(Postgres)を
Hyperdrive 経由で接続CI/CD:
push → GitHub Actions の workflow →
opennextjs-cloudflare(内部で wrangler を呼ぶ)→
Cloudflare Workers、という流れで自動デプロイ
画像をどこに置くか。それが問題だ。
この構成、そもそもの起点は
「R2 をどう活かすか」
にある。
掲示板・お知らせの画像を
大量に扱うサイトである以上、
画像ストレージの選び方が一番効いてくる。
そこから逆算して、フロントエンドも DB も
Cloudflare に寄せた、という順番。
ドメインも Cloudflare Registrar で取得している。
tarawo-girls.com と
tarawo-girls.academy の
2つを保有していて、
本番は tarawo-girls.academy を採用した。

ドメイン・DNS・ホスティング・ストレージまでは
全部 Cloudflare の管理画面一つで完結する。
DB 本体は Supabase(別サービス)だけど、
そこへの接続経路(Hyperdrive)だけは
Cloudflare 側で持つ、という構成になっている。
もちろん、ホスティングを Vercel にして
Vercel + Supabase + 画像だけ Cloudflare R2、
という組み合わせも技術的には十分成立する。
(R2 は S3 互換 API なので、
ホスティング先を問わず読み書きできるし、
エグレス無料もホスティング先を問わず効く)。
ただしその場合、
今回のように Workers の binding 経由で
R2 に直接・低レイテンシで
アクセスすることはできず、
公開 S3 API 経由のアクセスキー管理が要る。
掲示板の投稿画像を圧縮している
Cloudflare Images も
Workers 専用機能なので、
Vercel 側で同じことをするなら
sharp などを自前で挟む一手間が増える。
つまり、R2 を活かし切るなら
ホスティングも Cloudflare に寄せた方が
手数が少ない。
その一手間を避けたくて、
フロントエンドからストレージまで
Cloudflare 一本の構成にした。
技術的に重要なポイントを表にまとめるとこう。

DB に Supabase を選んだ理由は、
中身が素の Postgres だから。
Cloudflare D1 も検討したけれど、
SQLite ベースかつ Workers bindings に紐づく分、
将来自前の Postgres に乗り換えたく
なったときに身動きが取りにくいと判断した。
サーバレス構成上での Postgres は特性的に、
プーリングはほぼ必須(※後述)なので、
接続には Hyperdrive を経由させている。
(Cloudflare が用意している
プーリング&キャッシュ用のプロキシ)
サーバーレス環境はリクエストのたびに実行環境が
使い捨てで立ち上がるので、
素直に繋ぐと DB 接続がすぐ上限に達してしまう。
そこで少数の実接続を使い回す
「プーリング」を挟むことで、
大量の短命なリクエストを
さばけるようにしている。
Supabase Free プランの
DB ストレージは500MB までだけど、
画像は最初から R2 に逃がしていて、
Postgres 側には
R2 のオブジェクトキーや
投稿本文・タイムスタンプといった
メタデータしか持たせていない。
掲示板の投稿1件あたり
0.5〜2KB程度と見積もると、
500MBは単純計算で数十万件ぶん。
画像を DB に BLOB として
直接持たせる設計だったら
500MBはすぐ埋まっていたはずだけど、
R2 に分離してあるおかげで、
こちらは当分気にしなくていい容量になっている。
コストの考え方
今のところ、これは私が作りたくて作ったもの。
ドメイン代も欲しくて自分で買ったものだから、
ここまでの費用は気にしていない。
これから先も、私設にお金を絡ませるつもりはない。
となると、もし運営費用にランニングコストが
かかるようになった分は私の持ち出しになる。
だからこそ、無料枠は最大限使う。
R2 は毎月ストレージ10GB、
書き込み系操作100万回まで無料で、
なによりエグレス(外向き通信)が無条件で無料。
ファンコミュニティのサイトの画像程度なら、
当分この無料枠に収まる規模のはず。
画像ストレージの選択肢は他にもあるので、
無料枠だけ横並びにしてみた。

ストレージ量・エグレスとも R2 が頭一つ抜けてて、
GCS は無料枠はあるものの
2026年からは支払い情報の登録自体が必須になった。
今回みたいに「無料枠だけで気軽に運用したい」という
個人開発の要件には、R2 が一番素直に合っていた。
とはいえ、画像保存のストレージ利用料だけは、
他をどれだけ無料構成に寄せても
総量が増えるとどうしても発生してくるコストでもある。
継続的な課金が負担になるくらいデータが増えてきたら、
古い掲示板画像を低頻度アクセスストレージに移すとか、
保存期間そのものに制限をかけるとか、
そのあたりの対応をすることになりそう。
具体的にどれくらい保つか、
現在の会員数(50人前後)を前提に試算してみる。
投稿画像を1枚あたり最大5MBに圧縮する前提だと、
無料枠の10GBだけで2,000枚、
USD/JPY を余裕を見て170円換算した100円分を追加すると
約39GBぶん・7,800枚が積み増せる計算になる。
もっとも、これは
「全員が毎回上限ギリギリの重い画像を貼り続ける」
という技術上の最悲観シナリオでの試算。
招待制で、しかも強制退会もできる
会員制 BBS という性質上、
仮に荒らしのような投稿があっても
実際にはまず起こらない。
もう少し現実的に、
投稿画像の平均サイズを500KB〜1MBあたり
と見積もると、
無料枠の10GBだけで2万〜1万枚、
100円分を追加した約39GBで7.8万〜3.9万枚。
合計すると約10万〜5万枚が目安になる。
現実の消費ペースは、
最悲観シナリオよりずっとゆるやかになるはず。
作りながら踏んだ地雷、直した話
一人で作っていると、
後から気づいてヒヤッとすることもある。
役職を is_admin の真偽値1個で管理していたのを、
ロールベースの権限システムに作り直した
(「アカウント発行を何人かの管理者でやりたい」という
要求仕様がきっかけで、このタイミングで、ロール編集経由で
権限昇格できてしまう穴も塞いだ)掲示板の画像投稿で Server Actions の
ボディサイズ上限に引っかかったので、
Cloudflare の Images binding で
圧縮してから R2 に保存するようにしたスマホでネイティブの confirm() を
使っていた確認ダイアログを、
サイトのテーマに合わせた自前コンポーネントに置き換えたスマホでの文字サイズ崩れや、input フォーカス時に
iOS が勝手にズームしてしまう挙動も、後から直して回った
こういう
「動くには動くけど地味に気持ち悪い」
ところを一つずつ潰していく作業が、
個人開発では一番時間を食う。

それでも自分のペースで直せるのは、
気楽で楽しかった。
まとめ
掲示板の使い勝手も、
実際に学園生が使ってくれる中で
まだまだ改善していくつもり。
もし私設TG内に、この掲示板サイトの
共同開発に参加したい人がいたら、
tarawo-girls の org に招待もできるので、
気軽に連絡してほしい。

関連記事
この記事の前編
コミュニティ側の経緯や
コメント欄・DM のやり取りは
前編の記事にまとめてあるので、
興味があればそちらもどうぞ。
会長・ふらつき母ちゃんの広報記事
ふらちゃんが、会長みずから
学園サイトの正式広報を書いてくれたよ❣️✨️
おまけ
タラ様が毎日投稿の卒業後、
はじめての復帰記事をアップしてくれた❣️🫶
もう少し期間があくかと思ってたけど、
早めの復帰でめちゃくちゃ嬉しい❣️🥹
さいごに
Threads では、日々のことを
もう少し気ままに発信している。
よかったらのぞいてみて。

この記事がよかったら、
スキやコメント、フォローで
応援してもらえると嬉しい。
Marie