目的はSupabaseのサーバーとローカルの差がない状態にします。
環境
Windows11
VSCode Powershell
Next.15
Supabaeサーバーとローカルで開発
Drizzle ORM
現在の状況
サーバー側でもGUIでテーブルをイジり、ローカル側でもテーブルを色々と弄って、カオスになった状態。
決断
必要なテーブル、ファンクション、不要なテーブル、ファンクションが入り乱れて、リセットしたくなったので。
DockerのVolumesからリセットをすると決めました。
※ローカルもサーバーもリセットしたいときであって、サーバー側のデータやスキーマを残したいときは参考になりません。
やり方
DockerのVolumesの削除
Next.jsのSupabaseフォルダの削除(ローカル側のスキーマ)
をしてから、
supabase init とローカルを0から作り、その他色々とコマンドを打って、ローカルとサーバーとの差分を無くします。
ローカル <= Supabaseのローカル側開発環境のSupabase
サーバー <= Supabaseのサーバー側開発環境のSupabase
記録、メモ
もしSupabaseのサーバーとローカルの差がひどくなって修復不能だと思ったら
supabase db resetで大抵の問題は解決すると思いますが、
GUIで色々いじっていると修復不能に陥る時があります。
そんなときは思いきってローカル側を0から再生成しています。
supabase initからやり直すのです。
Supabaseの初期化
初期化前の準備
サーバーとローカルのバックアップを取れるなら取っておきます。
この方法は各自 好きな方法で行ってください。
ローカル側を完全に消して、
ローカルを新しく立ち上げて
サーバー側とのpullか差分diffをローカルに持ってきて同期させましょう。
※設定ファイル(config.toml)は別の場所に保存しておきます。
スキーマファイルは完全に同期した後に自由に使えばいいと思います。
DBはWebアプリには絶対必要で不可分だが、
Supabaseを外部ツールの一つと考え、気軽に再構築する
サーバーは作ってあるのを再利用します。
環境変数や、デプロイ先の設定をそのまま再利用できます。
やり直しのローカル
起動していたら停止させる
supabase stop
Docker の volumes を削除する
GUI Docker Desktopから削除
Supabaseのフォルダやファイルを消す
supabaseフォルダの削除
それぞれ再起動
再度初期化
supabase init
ローカルで起動させる時に
👇[analytics]をenabled = falseに設定する必要があります。
...
[analytics]
enabled = false
# Supabaseの開始
supabase start
# ログイン
supabase login
# 指示通りにログインをする。(サーバーは作ってあるのを再利用する場合)
# 現在のNext.jsアプリとSupabaseを選ぶ。
supabase link
# プロジェクトを選択
# これでサーバーとローカルが繋がりました。現状を調べていきます。
supabase migration list
# サーバー側だけスキーマがあり、ローカルは新規作成したので空です。
Local | Remote | Time (UTC)
-------|----------------|---------------------
| 20250908204338 | 2025-09-08 20:43:38
#ローカル側に新しくマイグレーションファイルを作ります。
supabase migration new schema
supabase migration list
Local | Remote | Time (UTC)
----------------|----------------|---------------------
| 20250908204338 | 2025-09-08 20:43:38
20250909005536 | | 2025-09-09 00:55:36
#サーバ側のスキーマを消します。
#(ココを残しておけばサーバーのスキーマやデータを残して置けると思います。たぶん)
supabase migration repair --status reverted 20250908204338
#ローカル側のスキーマファイルをサーバー側に適用します。
supabase migration repair --status applied 20250909005536
supabase migration list
Local | Remote | Time (UTC)
----------------|----------------|---------------------
20250909005536 | 20250909005536 | 2025-09-09 00:55:36
# supabase migration list はあくまでもローカル側から見た サーバーとローカルの同期の具合であることに注意してください。
# サーバーのスキーマをローカルに取り込み
supabase db pull
supabase migration list
supabase db push
Initialising cli_login_postgres role...
Connecting to remote database...
Remote database is up to date.
supabase db diff -f my_table <<確認、差分がないかを調べる
# 20250909013050_my_table.sqlが出力されました
# 中身を見るとなにか書かれています。
# サーバーとローカルとの間に差があるということです。
# ローカルの状況をサーバーに知らせます。
supabase db push
Do you want to push these migrations to the remote database?
• 20250909013050_my_table.sql
[Y/n]
# Yを押します。
supabase db pull
Schema written to supabase\migrations\20250909013314_remote_schema.sql
Update remote migration history table? [Y/n]
# Yを押します。
# 20250909013314_remote_schema.sql が作成されます。
# 中身を見てみます。
# この作成されたマイグレーションファイルの中身は空でした。
# これでマイグレーションファイルでも、実際のテーブルでも差分がないことが確認できました。
# 以上で作業は終了です。
# この後は Drizzle ORMなどで ローカルのSupabaseでNext.js 側のアプリ、スキーマを作成して、Trigger や Function も作成して、後でサーバーに反映していきます。
# 「サーバーのatuhスキーマ」には 直接ファイルから Triggerを設定できないので、 サーバー側のGUI(SQL Editor)から直接 Triggerのコードを書いて登録します。
db diffコマンド
supabase db diffコマンドの結果は、シャドウデータベース(マイグレーションを適用した理想状態)と現在のデータベースの状態を比較したものです。
ちょっとした疑問
Supabaseのサーバー側でテーブルをいじっても、ローカル側から見たらマイグレーションファイルのタイムスタンプが変わっていない、最新の状態なのか、古いマイグレーションファイルのままなのか不明なこと。
実際、サーバー側は最新の状態に 「反映されている」 が、ローカル側から見ると、マイグレーションファイルのタイムスタンプは変わらないし、新しいマイグレーションファイルも作られてないという状態だと思う。
これには、サーバー側のマイグレーションのタイムスタンプは1つだけだが、ローカル側のマイグレーションファイルは複数作れることに関係しているのだろう。
サーバー側が最新の状態だと判断できる安心するコマンドはないものか?
ローカルのSupabase CLIで サーバーのマイグレーションを新しい状態にする更新コマンドは無いのか?
※supabase migration listでは古いままで、サーバ側でいくらテーブルスキーマをいじっても古いまま。