← 記事一覧へ
AI生成画像

個人開発・スタートアップ向けのスタック:小さく作って、運用を軽くする

少人数で作って、少人数で運用し続けるための技術選びを、実際に動かしているWebアプリの構成(React Router、Cloudflare Workers、D1、Clerk)を例に整理する。

AI作成 · 約13分 · Webアプリを1つ作ったことがあれば十分
個人開発Cloudflareアーキテクチャ
この記事で扱うこと

小さなチームのスタックは、「速さ」より「運用の軽さ」で選びます。サーバーを持たない、認証は任せる、デプロイは自動、本番だけ人が確認する。この4つを軸にすると、少人数でも長く回せます。

小さなチームが技術を選ぶ基準

大きな会社の技術選びは、「何千人が使っても耐えるか」から考えます。個人開発や、創業直後のスタートアップは、別の問題を抱えています。人が少なく、時間が足りず、夜中に障害が起きても自分で直すしかありません。

この記事は、実際に動かしている小さなWebアプリ「PAIBOT.app」の構成を例に、少人数で作って、運用し続けるための選び方を整理します。選ぶときの基準は、次の5つです。

  1. サーバーを持たない:OSの更新や、サーバーの再起動、容量の心配を、自分で抱えない
  2. 固定費が小さい:使われなければ、ほとんどお金がかからない形から始められる
  3. 任せられるものは任せる:認証や、決済、メールなど、間違えると危ないものは、専門のサービスに任せる
  4. テストとデプロイが自動:少人数ほど、手作業の確認で時間を失う
  5. 後から動かせる:特定の会社にだけ縛られない作りにしておく

この記事の構成は、一つの例です。正解ではありません。サービスの機能、料金、無料枠は変わるので、使う前に、各社の公式ドキュメントで確認してください。

全体の構成

PAIBOT.appは、ブラウザで使える小さなツール集に、ログインとお気に入りの機能を足したWebアプリです。構成は次のとおりです。

小さなWebアプリの構成(React Router + Cloudflare)ブラウザClerk認証(外部サービス)サインイン本人を確認CloudflareWorkerReact Router のSSRとAPID1SQLite互換のDBWorkers AIモデルを呼ぶレート制限IPごとの回数静的ファイル画像・JS・CSSを配信
図1 サーバーは持たない。ブラウザからのリクエストをWorkerが受け、DB、AI、レート制限をバインディングで使う。認証は外部のサービスに任せる。
  • フレームワーク:React Router(フレームワークモード)。サーバー側で画面を作り(SSR)、ブラウザでは操作できる部品として動く
  • 実行環境:Cloudflare Workers。自分のサーバーはなく、世界中の拠点で、リクエストのたびにコードが動く
  • データベース:Cloudflare D1(SQLite互換)。ORMはDrizzleを使う
  • 認証:Clerk。ログイン画面も、パスワードの保存も、自分では作らない
  • AI:Workers AIをバインディングで呼ぶ。外部のAIサービスのAPIキーを持たずに済む
  • レート制限:Workersのレート制限機能で、IPごとの回数を絞る

各層の選択と理由

層選んだもの理由
画面React Router(SSR)検索エンジンに読まれる画面を、サーバー側で作れる。ルーティングとデータ取得が、1つの仕組みにまとまる
実行環境Cloudflare Workersサーバーの運用が要らない。使われない時間は、ほぼお金がかからない形から始められる
データD1 + Drizzle別のDBサーバーを立てなくてよい。型のあるクエリが書ける。スキーマの変更はマイグレーションで管理する
認証Clerk認証は、自作すると間違えやすく、間違えたときの被害が大きい。専門のサービスに任せる
国際化use-intl日本語、英語、中国語を、メッセージのファイルで管理する
テストNodeの標準テスト + Playwright計算などの部品は軽い単体テスト、画面はブラウザで1本の流れを確かめる
設定の管理Wrangler + Terraform同じものを2か所で管理しない。アプリに近いものはWrangler、アカウント全体の設定はTerraform

「Workersだから速い」「D1だから安い」ではなく、運用に手間がかからないことを理由にしています。

作る順番の工夫:ツール1つ、フォルダ1つ

ツールが増えても散らからないように、新しいツールは、1つのフォルダに、自分の部品をすべて入れる決まりにしています。画面、ロジック、単体テスト、ブラウザのテストが同じフォルダにあり、共通の一覧に登録するだけで、トップページの検索や、サイトマップにも反映されます。

  • 変更が影響するツールだけ、ブラウザのテストを動かす(共通の部品を変えたときは全部動かす)
  • 共通の確認(3つの言語で開ける、エラーが出ない、スマホ幅に収まる)は、テストを書かなくても、全ツールに自動で効く
  • 環境に依存するコード(Cloudflare専用の機能)は、サーバー専用のファイルに閉じ込める

最後の点は、「後から動かせる」ための工夫です。環境に依存する部分を薄い層にしておくと、実行環境を変えるときの影響が小さくて済みます。

デプロイの流れ

少人数のチームでは、デプロイを人の手でやるほど、ミスが増えます。PAIBOT.appでは、次の流れにしています。

変更が本番に出るまでの流れ変更を出す(PR)自動で検査型・単体テスト・ビルド・ブラウザテスト開発環境へ自動デプロイAccessで、許可した人だけが開ける本番は手動で実行開発で成功したかを確認。戻すときはタグを指定本番へデプロイDBのマイグレーションも同じ手順で自動人が確認
図2 検査と開発環境へのデプロイは自動で、本番だけ人が実行する。その手動の実行が、確認のステップになる。
  • 変更を出す(PR)たびに、型の検査、単体テスト、ビルド、ブラウザのテストを自動で動かす
  • メインに入ったら、開発環境へ自動でデプロイする。開発環境は、Cloudflare Accessで、許可した人だけが開けるようにしている
  • 本番は、人が手動で実行する。その変更が開発環境で成功していることを、本番の手順の中で確認する。問題があれば、タグを指定して、以前の版に戻せる
  • データベースの変更(マイグレーション)も、本番のデプロイの手順に含める

本番だけ手動にしているのは、「自動で全部が本番に出る」のが怖いからです。人が確認するステップが、手動の実行そのものです(当時は、チームの承認機能が、使っていたプランにはなかったため、この形にしました)。

実際に踏んだ罠

最初から今の構成だったわけではありません。このアプリは、最初はNext.jsを、ベータ版のアダプターでCloudflare Workersに載せて作りました。動きましたが、前例の少ない組み合わせで、認証ライブラリの読み込みや、国際化ライブラリの二重読み込みなど、接続部分で何度か詰まりました。結果として、Workersで素直に動く、React Routerに移しました。

ここから言えることは、次のとおりです。

  • 本番には、前例の多い組み合わせを選ぶ:ベータ版の部品が間に入ると、不具合の原因が、自分のコードか部品か分からなくなる
  • 詰まったら、二重のモジュールを疑う:同じライブラリが2つの経路で読み込まれると、片方の状態がもう片方に見えない。エラーの場所は、ライブラリの内部に出る
  • 移行できる形を保つ:境界を薄くしておいたので、大きな書き換えではなく、移行で済んだ

個人開発とスタートアップで、変えるところ

観点個人開発創業直後のスタートアップ
優先すること作り続けられること検証の速さと、後から直せること
認証任せる(自作しない)任せる。企業向けのログイン(SSO)が要るか早めに確認する
データベース小さく始める。1つにまとめる将来の移行を想定して、DBへのアクセスを1か所にまとめる
費用無料枠から始める無料枠が尽きる境目と、その後の料金を、先に見積もる
監視エラーを見られる最低限障害の連絡と、対応の担当を決める
人が増えたときあまり考えないテストと、デプロイの自動化が、人を増やす前提になる

選ぶときの注意

  • サービスへの依存:便利な機能ほど、そのサービスに寄ります。依存の入り口を、薄い層にまとめておくと、動かしやすい
  • 無料枠の落とし穴:無料枠が大きくても、条件や上限は変わる。使い方が増えたときの料金を、早めに見ておく
  • データの置き場所:ユーザーのデータをどこに置くか(地域、法令)は、後から変えにくい。早めに決める
  • 任せられないもの:権限の設計(誰が何を見られるか)は、サービスに任せても、設計は自分の仕事

確認リスト

  • 自分でOSやサーバーを管理しなくてよい構成になっているか
  • 認証や決済を、自作していないか
  • 変更を出すたびに、テストが自動で動くか
  • 本番へ出す前に、人が確認するステップがあるか。以前の版に戻す手順があるか
  • データベースの変更を、記録して管理しているか
  • 環境依存のコードが、1か所にまとまっているか
  • 無料枠の上限と、超えたときの料金を調べたか
  • 障害のときに、誰が気づいて、誰が直すかを決めたか

公式リファレンス

React Router — Documentation ↗Cloudflare Workers — Documentation ↗Cloudflare D1 — Documentation ↗Clerk — Documentation ↗Drizzle ORM — Documentation ↗
PAIBOT / DEVELOPMENT JOURNAL記事一覧に戻る →

知りたいことを探す

タイトル・タグ・本文から検索 esc で閉じる