個人開発を1台の VPS に載せて回す現実(PM2 / nginx / 役割分担)
複数サービスを1台に同居させつつ、アプリと DB の境界は混ぜない運用。
個人開発のサービスを、クラウドをサービスごとに散らばせず、1台の VPS に載せて回す運用をしています。Angla の AI プロキシ、管理画面、ブログ、問い合わせハブ、家計簿などが、同じマシン上の別プロセスとして動いています。
安さだけが目的ではなく、見渡しやすさと、障害時に SSH 一発で辿れることが大きいです。
何を分けて載せるか
だいたい次の単位で分けています。
- アプリ/サイトごとの PM2 プロセス
- ドメインごとの nginx 逆プロキシ
- データはサービスごとに 別 DB(Neon / Supabase / SQLite など)
「全部を一つの巨大アプリにしない」のが先です。同居するのはマシンであって、コードとデータの境界ははっきりさせます。
プロセスとドメイン
公開サイトはそれぞれドメイン(またはサブドメイン)を持ち、nginx がローカルのポートへ流します。TLS は Let's Encrypt でドメイン単位です。
デプロイは GitHub Actions から rsync / SCP して PM2 を再起動するパターンが多いです。サイトごとにワークフローは似ていますが、共有しすぎない方が事故が少ないです。
DB を同居させすぎない
昔は VPS 上の Postgres に寄せていたものも、負荷とメンテの都合で Neon へ移したものがあります。アプリの SQLite は「そのサイトの正本が VPS ローカル」と割り切るものもあります。
接続では、Neon の pooler で search_path が空になる、といった罠もありました。横断の話は別に書いています。
Neon の pooler と search_path
CI との役割分担
毎日必ず走るバッチまで GitHub Actions に寄せると、無料枠が先に死にます。Angla の日次スコアは VPS cron に移しました。
GitHub Actions から VPS cron へ
「変更時のデプロイは CI、定時は VPS」は、1台運用と相性がよいです。
壊したくないときのルール
運用しながら決めた、短いルールです。
- 本番の秘密は VPS 上の env に置き、デプロイで上書きしない
- ドキュメントだけの変更で重いジョブを巻き込まない
- レンダー中など長い処理があるときは、無闇に再起動しない
- 移行や接続変更は、ヘルスチェックと件数確認をセットにする
1台に載せるのは「雑に全部入れる」ことではなく、境界を保ったまま物理を共有することです。
まとめ
- 同居させるのはサーバー、混ぜないのはアプリと DB
- nginx + PM2 + ドメイン単位 TLS で見通しを保つ
- 定時バッチとデプロイ CI は役割を分ける
- 運用ルールは短く、破ると痛いところだけ書く
個別プロダクトの話は プロジェクト一覧 から辿れます。