深夜のマイグレーションという悪夢
migration failed: relation "users" already exists というエラーメッセージが赤々と表示される。時は午前2時。従来のPostgreSQLサーバーで、デプロイに失敗した環境のロールバックに四苦八苦している最中だ。スキーマが新旧の状態の間で立ち往生している間にも、新しいデータは次々と流れ込んでくる。選択肢は2つ。パニックになりながら手動でクエリを修正するか、昨晩のバックアップをリストアするために数時間分のデータを失うことを受け入れるかだ。
MySQL、MongoDB、Postgresを長年扱ってきた中で、Postgresはデータ整合性の面で常にトップだと感じている。しかし、そのステージング環境の管理は苦行だ。500GBのデータベースを複製し、わずか10分のマイグレーションスクリプトを実行するためだけに準備することは、通常のRDSシステムではほぼ不可能に近い。
Neonの登場はこの状況を完全に変えた。自動スケーリングが可能なServerless PostgreSQLであるだけでなく、Neonは究極の武器「Database Branching」を備えている。Copy-on-Write技術により、テラバイト級の本番データベースのコピーをわずか2秒足らずで作成できるのだ。あなたのCI/CDワークフローは、今日から新しいステージへと進むだろう。
Neonプロジェクトの設定:ゼロから接続文字列まで
面倒なDockerやサーバー設定のことは忘れよう。Neonはストレージ層とコンピューティング層を完全に分離しているため、セットアップが驚くほど速い。
まずは neon.tech にアクセスしてアカウントを作成する。プロジェクトを作成すると、次のような構造の接続文字列(Connection String)が発行される。
postgres://alex:[email protected]/neondb?sslmode=require
個人的に非常に気に入っているのが Autoscale 機能だ。最小値を0.25 CU(Compute Unit)に設定できる。トラフィックがない時はデータベースが自動的に「スリープ」状態(Scale to zero)になる。これにより、開発環境やユーザーの少ないサイドプロジェクトでは、コストを最大90%削減できる。
Neon CLIをプロのように使いこなす
Webインターフェースでの操作も便利だが、生産性を最大限に高めるならCLIを使うのがエンジニアの流儀だ。以下のツールをインストールしよう。
npm install -g neonctl
neonctl auth
ブラウザ経由での認証が終われば、ターミナルからデータベースインフラ全体を操作できる準備が整う。
Database Branching:データのための真のGit
通常、新機能をテストするには本番データをローカルにダンプする必要がある。この方法は時間がかかるだけでなく、機密データ漏洩のリスクも孕んでいる。Neonなら、各データベースブランチが独立した環境として機能する。
例えば、main ブランチにいて、orders テーブルにカラムを追加するスクリプトをテストしたいとする。直接操作してはいけない。専用のブランチを作成しよう。
# 'main'ブランチから'feature-add-column'ブランチを作成
neonctl branches create --name feature-add-column --parent-id main
# 即座に接続するための接続文字列を取得
neonctl connection-string feature-add-column
このブランチ上での ALTER TABLE やデータの削除といった変更は、元のデータには一切影響しない。もし失敗しても、削除して最新の本番データから新しいブランチを作り直すのに、わずか2秒しかかからない。
GitHub Actionsに統合して完全自動化する
私はよくNeonをCI/CDワークフローに組み込んで、プレビュー環境を構築している。プルリクエスト(PR)が作成されるたびに、システムが自動的に専用のデータベースブランチを作成する。統合テスト(Integration Test)はこの実データ上で直接実行される。
以下は、このプロセスを自動化するためのワークフローのサンプルだ。
name: Preview Environment DB
on: [pull_request]
jobs:
setup-db:
runs-on: ubuntu-latest
steps:
- name: Create Neon Branch
id: create-branch
run: |
# PR用の新しいブランチを作成するためにNeon APIを呼び出す
BRANCH_DATA=$(curl -X POST "https://console.neon.tech/api/v2/projects/${{ secrets.NEON_PROJECT_ID }}/branches" \
-H "Authorization: Bearer ${{ secrets.NEON_API_KEY }}" \
-H "Content-Type: application/json" \
-d '{"branch": {"name": "pr-${{ github.event.number }}"}}')
DB_URL=$(echo $BRANCH_DATA | jq -r '.connection_uris[0].connection_uri')
echo "DATABASE_URL=$DB_URL" >> $GITHUB_ENV
- name: Run Migrations and Tests
run: |
npm install
npx prisma migrate deploy
npm test
PRがマージされると、別のジョブがこのブランチを削除してリソースを最適化する。この手法により、各開発者が独立した安全な遊び場を持つことができる。
実戦経験:よくある「落とし穴」を避けるために
Neonは非常に柔軟だが、システムを円滑に運用するために以下の3点に注意してほしい。
- コールドスタートへの対応: サーバーレスモードでは、クエリがないとデータベースが一時停止する。初回アクセス時に500msから2秒程度の遅延が発生する可能性がある。即時のレスポンスが必要なアプリでは、
min_cuを0より大きく設定し、常にデータベースを「温めて」おく必要がある。 - コネクションプーリングの活用: NeonにはPgBouncerが標準で統合されている。常にポート
5432または末尾に-poolerが付いたエンドポイントを使用すること。これにより、トラフィックが急増した際に応プリケーションが「too many connections」エラーで停止するのを防げる。 - 定期的なクリーンアップ: ブランチ作成は容量ベースでは無料だが、プランによって作成できる数に制限がある。作業が終わったらテスト用ブランチを削除する習慣をつけよう。
ダッシュボードで指標を確認することも欠かせない。CPUが頻繁に100%に達する場合は、Max CU の上限を引き上げるか、EXPLAIN ANALYZE を使って遅いクエリを最適化しよう。データベースをコードのように柔軟に作成・削除できるリソースとして捉えることで、プロジェクトの開発スピードは劇的に向上するはずだ。

