個人開発SaaSを月額ほぼ0円で動かす Cloudflare Pages+D1構成ガイド
結論:Cloudflareだけで月額ほぼ0円のSaaSインフラが成立する
個人開発でSaaSを立ち上げる最大の壁は「収益が出る前のインフラコスト」です。VPSやRDSを使うと月1〜3万円は軽くかかり、PMF前に資金が尽きるリスクがある。
その解決策が Cloudflare Pages+D1+Workers+R2 の組み合わせです。すべてCloudflareの無料枠または従量課金の範囲に収まり、小〜中規模SaaSなら月額ほぼ0〜数百円で本番運用できます。
免責: 無料枠の上限・料金体系は変更される場合があります。実装前にCloudflare公式の最新料金ページを必ず確認してください。
各サービスの無料枠早見表
| サービス | 用途 | 無料枠の目安 |
|---|---|---|
| Cloudflare Pages | フロントエンドホスティング | ビルド500回/月、帯域無制限 |
| Cloudflare Workers | APIサーバー/BFF | 10万リクエスト/日 |
| Cloudflare D1 | SQLiteベースのRDB | 5GBストレージ、500万行読み取り/日 |
| Cloudflare R2 | オブジェクトストレージ | 10GB/月、Aクラス100万回/月 |
| Cloudflare KV | セッション・キャッシュ | 10万回読み取り/日 |
月間アクティブユーザーが数百〜数千人規模であれば、無料枠を超えることはほぼありません。超えた場合も従量課金は安価(Workersは100万リクエストあたり$0.30)です。
全体構成図
┌─────────────────────────────────────────────────────┐
│ Cloudflare Network │
│ │
│ ┌──────────────┐ ┌──────────────────────────┐ │
│ │ Cloudflare │────▶│ Cloudflare Workers │ │
│ │ Pages │ │ (Hono / API Routes) │ │
│ │ (Astro/React)│ └───────────┬──────────────┘ │
│ └──────────────┘ │ │
│ ┌────────┼────────┐ │
│ ▼ ▼ ▼ │
│ ┌───┐ ┌───┐ ┌───┐ │
│ │ D1│ │ KV│ │ R2│ │
│ │SQL│ │KVS│ │S3 │ │
│ └───┘ └───┘ └───┘ │
└─────────────────────────────────────────────────────┘
▲ │
│ 外部連携 │
│ (Stripe Webhook, etc.) │
└──────────────────────────┘
フロントエンドはCloudflare Pagesでホストし、APIはWorkersで処理。データはD1(構造化データ)・KV(セッション、レートリミット)・R2(ファイル)に分けて格納するのが基本パターンです。
実装パターン:HonoでAPI Workersを作る
Workers上で動くAPIフレームワークとして Hono が最もおすすめです。軽量かつTypeScript対応が優秀で、D1バインディングとの相性も抜群。
プロジェクト初期化
npm create cloudflare@latest my-saas-api -- --template hono
cd my-saas-api
wrangler.toml の設定
name = "my-saas-api"
compatibility_date = "2024-11-01"
[[d1_databases]]
binding = "DB"
database_name = "my-saas-db"
database_id = "xxxx-xxxx-xxxx" # wrangler d1 create で発行
[[kv_namespaces]]
binding = "SESSION"
id = "xxxxxxxx"
[[r2_buckets]]
binding = "STORAGE"
bucket_name = "my-saas-storage"
D1を使ったCRUDエンドポイント例
// src/index.ts
import { Hono } from 'hono'
import { cors } from 'hono/cors'
type Bindings = {
DB: D1Database
SESSION: KVNamespace
STORAGE: R2Bucket
}
const app = new Hono<{ Bindings: Bindings }>()
app.use('*', cors({ origin: 'https://your-saas.pages.dev' }))
// ユーザー一覧取得
app.get('/api/users', async (c) => {
const { results } = await c.env.DB.prepare(
'SELECT id, email, plan, created_at FROM users ORDER BY created_at DESC LIMIT 50'
).all()
return c.json(results)
})
// ユーザー作成
app.post('/api/users', async (c) => {
const { email, plan } = await c.req.json<{ email: string; plan: string }>()
const result = await c.env.DB.prepare(
'INSERT INTO users (email, plan, created_at) VALUES (?, ?, ?) RETURNING *'
)
.bind(email, plan, new Date().toISOString())
.first()
return c.json(result, 201)
})
export default app
D1マイグレーション
-- migrations/0001_create_users.sql
CREATE TABLE IF NOT EXISTS users (
id TEXT PRIMARY KEY DEFAULT (lower(hex(randomblob(16)))),
email TEXT UNIQUE NOT NULL,
plan TEXT NOT NULL DEFAULT 'free',
created_at TEXT NOT NULL
);
CREATE INDEX idx_users_email ON users(email);
# ローカルに適用
npx wrangler d1 execute my-saas-db --local --file=migrations/0001_create_users.sql
# 本番に適用
npx wrangler d1 execute my-saas-db --file=migrations/0001_create_users.sql
フロントエンド(Astro)をPagesにデプロイ
Cloudflare Pagesは静的サイトのみならず、Astro SSRもサポートしています。
npm create astro@latest my-saas-front
cd my-saas-front
npx astro add cloudflare # Cloudflareアダプタを追加
astro.config.mjs にアダプタを設定後、GitHubリポジトリをPagesのダッシュボードに接続するだけでCI/CDが完成します。プッシュするたびに自動ビルド・デプロイが走る。
R2でファイルアップロードを実装する
// ファイルアップロードエンドポイント
app.post('/api/upload', async (c) => {
const formData = await c.req.formData()
const file = formData.get('file') as File
if (!file) return c.json({ error: 'No file' }, 400)
const key = `uploads/${crypto.randomUUID()}-${file.name}`
await c.env.STORAGE.put(key, file.stream(), {
httpMetadata: { contentType: file.type },
})
// 署名付きURLを返す(7日間有効)
const url = await c.env.STORAGE.createPresignedUrl?.('GET', key, { expiresIn: 604800 })
return c.json({ key, url })
})
コスト比較:従来構成 vs Cloudflare構成
| 項目 | VPS+RDS構成 | Cloudflare構成 |
|---|---|---|
| サーバー | VPS 月2,000〜5,000円 | Workers 月0円〜 |
| DB | RDS最小 月3,000〜 | D1 月0円〜 |
| ストレージ | S3互換 月数百円〜 | R2 月0円〜(10GB) |
| CDN | 別途設定 月数百円〜 | Pages込み 0円 |
| 合計 | 月5,000〜10,000円 | 月0〜数百円 |
初期フェーズの数ヶ月をほぼ無料で乗り越えられるのは、個人開発者にとって大きなアドバンテージです。
注意点・デメリット
- D1はSQLiteベースのため、PostgreSQL固有の機能(配列型、全文検索など)は使えない。複雑なクエリが必要なら設計を工夫するか、Hyperdrive経由で外部DBを使う検討も必要。
- Workersのコールドスタートは基本なしだが、CPU時間は無料プランで10ms/リクエストの制限がある。重い処理には向かない。
- D1はまだGA(一般提供)が新しいサービスのため、大規模トランザクションや高頻度書き込みには本番実績を確認してから採用すること。
- 日本のデータ主権・個人情報保護法の観点から、データのリージョン制御が必要な場合は別途検討が必要。
まとめ
| ステップ | やること |
|---|---|
| 1 | wrangler d1 create でDBを作成 |
| 2 | Honoでapi Workersを実装・デプロイ |
| 3 | AstroフロントエンドをPages に接続 |
| 4 | R2バケットを作りファイルアップロードを追加 |
| 5 | KVでセッション・レートリミット管理を実装 |
Cloudflare Pages+D1+Workers+R2の組み合わせは、個人開発SaaSの初期コスト問題を根本から解決する現時点で最有力の選択肢の一つです。無料枠が充実しているため、PMFを確認してから課金プランに移行するという戦略が取りやすい点も大きな魅力です。
まずはローカルでwrangler devを動かし、小さな機能から試してみてください。Cloudflareのエコシステムは一度覚えると非常に生産性が高く、個人開発の強力な武器になります。