はじめに
Vercel と Neon PostgreSQL を使用してNext.jsアプリケーションを開発していたところ、データベース接続エラーに遭遇しました。環境変数を正しく設定したはずなのに、なぜか古いデータベースURLが使われ続ける謎の現象です。
Error [PrismaClientInitializationError]:
Can't reach database server at `ep-yellow-river-a4iye64q-pooler.us-east-1.aws.neon.tech:5432`
調査の結果、これは Vercel-Neon Integration の仕様による問題であることが判明しました。同じ問題で困っている方のために、原因と解決策を共有します。
問題の概要
発生した状況
- Neon でデータベースのブランチ整理を実施
- コンピュートエンドポイントが変更された(
ep-yellow-river
→ep-long-flower
) -
.env.local
と Vercel の環境変数を新しいURLに更新 - 再デプロイしても 古いデータベースURL が使われ続ける
- 手動で環境変数を削除・追加しても効果なし
原因:Vercel-Neon Integration の自動管理機能
Vercel-Neon Integration には以下の特徴があります:
-
DATABASE_URL
を 自動的に管理・注入 する - 手動で環境変数を変更しても デプロイ時に上書き される
- Integration 内部にURLを保持し続ける(削除しても効果なし)
これは「バグ」ではなく、意図された仕様です。しかし、以下の問題があります:
-
Neon側の変更が自動反映されない
- エンドポイント変更時の自動更新機能がない
- 古いURLを注入し続ける
-
手動での制御が効かない
- 環境変数の削除・更新が無視される
- 「ゴースト変数」として残る
解決策
解決策1: カスタム環境変数名を使用(推奨)
最も簡単で確実な方法です。
1. Prisma スキーマを変更
// prisma/schema.prisma
datasource db {
provider = "postgresql"
url = env("CUSTOM_DATABASE_URL") // DATABASE_URL → CUSTOM_DATABASE_URL
}
2. ローカル環境変数を更新
# .env.local
CUSTOM_DATABASE_URL=postgres://user:pass@new-endpoint.neon.tech/db?sslmode=require
3. Vercel に環境変数を追加
# すべての環境に追加
echo "your-database-url" | vercel env add CUSTOM_DATABASE_URL production
echo "your-database-url" | vercel env add CUSTOM_DATABASE_URL preview
echo "your-database-url" | vercel env add CUSTOM_DATABASE_URL development
4. Prisma クライアントを再生成
npm run prisma:generate
5. 再デプロイ
vercel --prod --force
解決策2: Vercel のビルドターゲット設定
Vercel環境でPrismaを使用する場合、適切なバイナリターゲットが必要です。
generator client {
provider = "prisma-client-js"
binaryTargets = ["native", "rhel-openssl-3.0.x"]
}
解決策3: Integration を削除して手動管理
根本的に解決したい場合は、Integration自体を削除します。
# Integration のリソースを確認
vercel integration list
# リソースを削除してから Integration を削除
# (Vercel ダッシュボードから実行)
なぜこの問題が起こるのか
Integration の設計思想
Vercel-Neon Integration は、開発者の手間を減らすために環境変数を自動管理します。これは通常は便利ですが、以下の場合に問題となります:
-
Neon側でインフラ変更があった場合
- ブランチの再作成
- コンピュートエンドポイントの変更
- リージョンの移行
-
複数のデータベースを使い分けたい場合
- 開発用と本番用で異なるインスタンス
- A/Bテスト用の環境
-
手動でのきめ細かい制御が必要な場合
- 接続プーリングの設定変更
- タイムアウト値の調整
技術的な詳細
Integration は以下のタイミングで環境変数を注入します:
-
ビルド時:
process.env.DATABASE_URL
として注入 - ランタイム: サーバーレス関数の実行時に注入
削除しても効果がない理由:
- Integration 内部のストレージに保持
- Vercel のキャッシュメカニズム
- デプロイメントごとの動的注入
トラブルシューティング
デバッグ方法
1. 現在の環境変数を確認
# Vercel の環境変数リスト
vercel env ls production
# ローカルに環境変数をダウンロード
vercel env pull .env.vercel
2. Integration の状態確認
vercel integration list
3. キャッシュのクリア
# 強制的に再デプロイ
vercel --prod --force
よくあるエラーと対処法
エラー1: PrismaClientInitializationError
Can't reach database server at `old-endpoint.neon.tech:5432`
対処法: カスタム環境変数名を使用
エラー2: Integration 削除時のエラー
Error: Cannot uninstall integration with resources (403)
対処法: Vercel ダッシュボードからリソースを先に削除
エラー3: 環境変数が反映されない
対処法:
- すべての環境(production, preview, development)に設定
- キャッシュをクリア
- 強制再デプロイ
まとめ
Vercel-Neon Integration の自動管理機能は便利ですが、手動制御が必要な場合は制限となります。カスタム環境変数名を使用することで、この問題を簡単に回避できます。
ポイント
- 🔧 Integration は
DATABASE_URL
を自動的に上書きする - 🚫 手動での削除・更新は無視される
- ✅
CUSTOM_DATABASE_URL
などの別名を使用すれば解決 - 📝 Prisma スキーマの変更を忘れずに
この問題は Vercel と Neon の公式ドキュメントでも言及されていますが、実際に遭遇すると原因が分かりにくいため、この記事が参考になれば幸いです。