自前VPSを選ぶ理由
国内VPSは価格が下がっていて、2コア/メモリ2GB/NVMe 200GBクラスで月770円〜という価格帯も出てきています。Cloud RunやCloudflare Workersのような無料枠の上限を気にする必要がなく、スペックを決めた時点で毎月の費用がほぼ固定されます。
構成はシンプルです。VPS1台の中に、リバースプロキシ兼HTTPS終端のCaddy、データベースのPostgreSQL、systemdで常駐させるアプリ本体(Next.jsやGo)を同居させます。この3点がこの手引の自前サーバー構成の最小単位で、Caddyの基礎・Next.jsの基礎で個別に扱っている内容の組み合わせです。
サーバーを自由に構築できる
root権限があるので、ミドルウェア、言語ランタイム、常駐プロセスの組み合わせを自分で選べます。マネージドサービスの実行時間やランタイムの制限に縛られません。
CDNは挟む前提で設計する
VPSを直接インターネットに晒さず、Cloudflareなどのcdnを前段に置きます。オリジンのIPを隠し、静的アセットをキャッシュし、DDoSの矢面を肩代わりさせます。
画像・ファイルはR2に逃がす
利用者がアップロードする画像や添付ファイルは、VPSのディスクや帯域を使わず、Cloudflare R2に保存してCloudflare経由で配信します。R2は転送量(エグレス)に課金されないため、画像が多いサービスほどVPS側の帯域を圧迫せずに済みます。
もう一つの利点は、アクセスが急に伸びたときの費用です。SupabaseのAuthは無料枠(月5万MAU)を超えると1MAUあたり0.00325ドルの従量課金になります。自前で認証を実装してVPS上で動かす場合、利用者が増えてもサーバー費用はスペックを上げない限り変わりません。SNSなどで急にアクセスが伸びた場合、従量課金のサービスほど費用が跳ねやすく、固定費のVPSの方が有利に働く場面があります。
基本のデプロイ経路
GitHubへ変更を送る
レビューできる差分として記録します。
GitHub Actionsで検査
Lint、型チェック、ユニットテスト、ビルドを実行します。
成果物を保存
合格したNext.jsのビルド成果物へ、GitのコミットIDを基にした版を付けて保存します。
Ansibleで本番反映
承認した版をLinuxサーバーへ配置し、systemdサービスを切り替えてヘルスチェックします。
ユニットテストをデプロイの関門にする
AIには機能の実装だけでなくテストも書かせます。GitHub Actions上でテストが一つでも失敗した場合、本番反映へ進まないようにします。
- ユニットテスト:計算、検証、権限判定
- 型チェック・Lint:基本的な不整合
- E2Eテスト:ログインから主要操作まで
- ビルド:本番用成果物を作れるか
セルフホステッドランナーを本番へ直接置かない
セルフホステッドランナーはGitHub Actionsの指示でコマンドを実行します。本番サーバーへ置くと、ワークフローや依存関係が侵害されたときに、本番環境の権限まで渡すことになります。
必要なら専用の管理VMに置き、プライベートな管理経路から本番へ接続します。対象はプライベートリポジトリに限定し、外部からのPull Requestでは実行させず、本番用シークレットと承認権限も分離します。
失敗時に前の版へ戻せるようにする
ビルド成果物をバージョン別のディレクトリへ配置し、現在使用する版を切り替えられるようにします。直前の正常版を残し、systemdの再起動後にヘルスチェックとログを確認します。DBマイグレーションには後戻りできない変更があるため、バックアップと適用順序を確認してから実行します。
バックアップはVPSの外、別クラウドに置く
VPS事業者のスナップショット機能だけに頼ると、その事業者側の障害やアカウント停止で、本番データとバックアップを同時に失うリスクが残ります。PostgreSQLのダンプと利用者のアップロードファイルは、VPS事業者とは別のクラウドにも複製しておきます。
Backblaze B2はS3互換のオブジェクトストレージで、ストレージは1TBあたり月6ドルから、最初の10GBは無料です。保存しているデータ量の3倍まではダウンロード(エグレス)も無料枠に含まれるため、定期的なバックアップの保存先として費用を抑えやすいサービスです。