はじめに
最近、個人で開発しているサービスのデータベースを
Neon → 自前PostgreSQL に移行しました。
Neonはとても優れたサービスです。
サーバレスでスケールするし、ブランチ機能も便利で、開発体験も良い。
ただ実際にサービスを運用してみると、少し気になる点も出てきました。
一番大きかったのは 転送量の制限です。
Neonの無料プランには
Monthly public network transfer
5GB
という制限があります。
最初は「5GBあれば十分かな」と思っていました。
しかし、私のサービスでは
1日500記事程度
の収集と処理を行っているため、思ったよりデータベースとの通信量が増えます。
もちろん有料プランにすれば解決します。
Neonの有料プランは
$19 / month
です。
ただその時にふと思いました。
「この規模なら自前DBでもいいのでは?」
最近はクラウドVMも安いですし、
PostgreSQLも非常に安定したデータベースです。
そこで今回は 自前PostgreSQL環境を構築することにしました。
使用したインフラ構成
今回構築した構成は以下です。
Internet
↓
Caddy (HTTPS)
↓
CloudBeaverApp
↓
PgBouncer :6432
↓
PostgreSQL :5432CI (GitHub Actions)
↓
Tailscale
↓
PostgreSQL
この構成により
- DBポートをインターネットに公開しない
- GitHub Actions から migration 実行
- Web UI で DB 管理
が可能になります。
Oracle Cloud Infrastructure (OCI) を使用
今回のVMは
Oracle Cloud Infrastructure (OCI)
を使いました。
OCIを選んだ理由は次の通りです。
- ARM VM が安い
- Always Free がある
- Block Volume が安い
- ネットワーク帯域が広い
今回作成したVMは以下です。
VM.Standard.A1.Flex
1 OCPU
ストレージは
Block Volume
200GB
データベース用途としては十分な容量です。
PostgreSQL のインストール
Ubuntuで普通にインストールします。
sudo apt update
sudo apt install postgresql
インストール後、ポートを確認します。
ss -lntp | grep 5432
PostgreSQLはデフォルトで
5432
をリッスンします。
PgBouncer を導入する理由
アプリケーションからの接続は PgBouncer を使います。
理由はPostgreSQLの接続コストです。
App
↓
PgBouncer
↓
Postgres
という構成にすると
- 接続数削減
- CPU負荷軽減
- DB安定性向上
などのメリットがあります。
今回の構成は
PgBouncer :6432
Postgres :5432
です。
golang-migrate が PgBouncer で動かない問題
データベースの migration には
golang-migrate
を使用しています。
しかしここで問題が発生しました。
golang-migrate
は migration の衝突を防ぐために
Postgres advisory lock
を使用します。
一方、PgBouncer の
transaction pooling
モードでは、このロックが正常に動作しません。
つまり
migration
↓
Postgres直
で実行する必要があります。
Tailscale を使って DB ポートを非公開にする
そこで導入したのが
Tailscale
です。
Tailscaleは
WireGuardベースのメッシュVPN
です。
VMにインストールします。
curl -fsSL https://tailscale.com/install.sh | sh
ログインします。
tailscale up
すると次のようなIPが付きます。
100.102.124.117
さらに MagicDNS により
postgres.tailXXXX.ts.net
というホスト名でもアクセスできます。
GitHub Actions から golang-migrate を実行
GitHub Actionsからは
Tailscale GitHub Action
を使います。
これにより
GitHub Actions
↓
Tailscale
↓
Postgres
の接続が可能になります。
接続URLは次のようになります。
postgres://user:password@postgres.tailXXXX.ts.net:5432/db
CloudBeaver を導入して DB をブラウザ管理
DBの管理には
CloudBeaver
を使っています。
CloudBeaverは
- WebブラウザからDB操作
- PostgreSQL / MySQL / etc 対応
- DBeaver互換
のツールです。
Dockerで簡単に動きます。
docker run -d \
--name cloudbeaver \
-p 127.0.0.1:8978:8978 \
dbeaver/cloudbeaver
Caddyで
sql.example.com
にリバースプロキシしました。
NeonからPostgreSQLへデータ移行
移行は非常に簡単でした。
まず dump を取得します。
pg_dump $NEON_DATABASE_URL > dump.sql
次に restore。
psql $NEW_DATABASE_URL < dump.sql
PostgreSQL同士なので問題なく移行できます。
最終構成
最終的な構成は次の通りです。
Internet
↓
443 → Caddy
↓
CloudBeaverApp
↓
PgBouncer :6432
↓
PostgreSQLCI
↓
Tailscale
↓
PostgreSQL
公開ポートは
443
6432
のみです。
まとめ
Neonは非常に便利なサービスですが、
小規模な個人サービスであれば
自前PostgreSQL
も十分選択肢になります。
特に
OCI + PgBouncer + Tailscale
の構成は
- コスト
- セキュリティ
- 自由度
のバランスがとても良いと感じました。
個人サービスのデータベース構成としては、
かなり満足度の高い環境になりました。


コメント