RenderからNeonへDB移行したら、間違ったリポジトリを本番運用していたことに気づいた

JavaScript

1. きっかけ:Renderの無料PostgreSQLが90日で消えた

ある日、いつものように開発中のアプリを触ろうとしたら、DBの中身が空っぽになっていました。

一瞬「え、何かやらかした?」と血の気が引きましたが、調べてみるとRenderの無料PostgreSQLプランには90日で自動削除されるという仕様がありました。使い始めた頃にお知らせは来ていたはずですが、見事にスルーしていたようです。

無料枠なので文句は言えませんが、こういう「期限つきの無料」は本当に忘れた頃にやってきます。

2. NeonとSupabaseを比較した

このタイミングで、そもそも無料のPostgreSQLサービスをどこにするか考え直すことにしました。候補は以下の2つ。

NeonSupabase
無料枠の期限無期限無期限(ただし一定期間アクセスがないと一時停止)
停止からの復帰自動手動操作が必要な場合あり
用途PostgreSQLのみPostgreSQL+認証・ストレージ等のBaaS

今回はDB単体として使えれば十分だったのと、「無期限・自動復帰」という組み合わせがシンプルで安心できたので、Neonを選びました。

3. Neonへの移行手順

プロジェクト作成・接続文字列の取得

Neonでプロジェクトを新規作成し、接続文字列(postgres://...形式)を取得します。

ローカルの.envを更新

# backend/.env
DATABASE_URL=postgres://xxxxx@xxxxx.neon.tech/xxxxx

マイグレーション不要だった話

移行と聞くとテーブル定義を作り直す作業を身構えますが、今回はアプリ起動時にinitDb()が自動でテーブルを作成する仕組みになっていたため、追加のマイグレーション作業は不要でした。過去の自分に感謝したい瞬間です。

ローカルで起動確認

npm run dev

問題なく動くことを確認したら、次はRender側の設定を変更します。

Renderの環境変数を更新

Renderの管理画面からDATABASE_URLをNeonの接続文字列に差し替えます。

古いRenderのPostgreSQLを削除

動作確認が済んだら、もう用済みになったRenderのPostgreSQLインスタンスを削除。これでDB移行自体は完了です。

ここまでは特に問題なく進み、「意外とあっさり終わったな」と思っていました。この後にもっと大きな落とし穴が待っているとも知らずに。

4. 「あれ、テストデータが本番に出ない」事件

移行後の動作確認も兼ねて、テストデータを投入してみました。ところが、本番の一覧画面を見てもそのデータが反映されません。

「Neonへの接続がうまくいってない?」「キャッシュ?」と疑いながら調査を始めたのですが、原因はまったく別のところにありました。

5. 原因調査:originが別のリポジトリを指していた

ローカルのgitリポジトリを確認したところ、originが指していたのはkenichi046/develp-starrtという、なんだか見覚えのある、でも微妙に違うリポジトリでした。

しかもそのmainブランチはコミットが3つしかない、明らかに開発初期の状態。

一方でRenderが実際にデプロイしていたのは、別の正しいリポジトリkenichi046/darts-self-introduction-card-match44コミット目。プロフィール画像アップロードやSNSリンク機能など、あとから追加した機能がごっそり含まれている状態でした。

つまりローカルでは3コミット目の世界線で作業しながら、本番は44コミット先を走っていたということです。テストデータが本番に反映されないのも当然でした。

6. 復旧作業:正しいorigin/mainへの統合

まずoriginのURLを正しいリポジトリに修正します。

git remote set-url origin <正しいリポジトリのURL>
git fetch origin

このとき、古いローカルのmainブランチにも作業中の変更(マソンリーレイアウトのUI改修など)が残っていたので、一旦バックアップ用のブランチに退避しました。

git branch backup-old-main main

そのうえで、mainを正しいorigin/mainにリセットします。

git checkout main
git reset --hard origin/main

退避しておいたUI変更は、新しいコードベースに合わせて書き直しながら再適用しました。3コミット目基準で書いたコードをそのまま44コミット目に持ち込むと、当然ながらあちこち噛み合わないので、ここは素直に手作業でした。

7. まとめ

内容
きっかけRenderの無料PostgreSQLが90日で削除される仕様だった
移行先Neon(無期限無料枠・自動復帰が決め手)
移行作業initDb()のおかげでマイグレーション不要、環境変数の差し替えのみ
見つかった事故ローカルのoriginが別リポジトリを指しており、41コミット分の差分があった
教訓無料枠の期限は最初に確認する/git remote -vは定期的に見直す

DB移行そのものは拍子抜けするほど簡単でした。本当に厄介だったのは、その裏に隠れていた「実は違うリポジトリを見ていた」という事故の方です。

「無料だから」と気軽に始めたものほど、後から思わぬ形で足元をすくわれるものだなと実感した一件でした。

タイトルとURLをコピーしました