[Supabase] ローカル環境で2プロジェクトを同時起動する手順(ポート競合の回避)

背景

この対応の発端は、supabase start 実行時のポート競合エラーだった。

  1. 1回目の supabase start はDocker daemon未接続で失敗
  2. Docker起動後、2回目の supabase start でイメージPullまでは進んだが、54322 競合で失敗
  3. Supabase CLIから「停止か、DBポート変更」の案内が表示された
error
failed to start docker container: ... Bind for 0.0.0.0
failed: port is already allocated Try stopping the running project with supabase stop --project-id onidazo_project Or configure a different db port in supabase/config.toml

CLIの案内どおり、次の2択で対処する流れになった。

  • supabase stop --project-id onidazo_project で稼働中プロジェクトを停止する
  • supabase/config.toml のDBポートを変更する

対処の方針

稼働中プロジェクトは開発を継続したいので停止したくない。 そこで、もう一方の案である「ポート分離」で2プロジェクトを共存させる方針にした。

方針

Supabaseプロジェクトは2つ同時起動できる。 ただし、次の2点が必要になる。

  • project_id を重複させない
  • 使用ポートを重複させない

どこまでポートを分けるべきか

db.port だけでは不十分なことがある。
同時起動を安定させるなら、次をまとめて分離する。

  • api.port
  • db.port
  • db.shadow_port
  • db.pooler.port
  • studio.port
  • inbucket.port
  • analytics.port
  • edge_runtime.inspector_port

具体例(今回の変更)

対象ファイル: supabase/config.toml

衝突元が 54322db.port)だったため、2つ目プロジェクト側を 55320 番台にずらして、関連ポートもまとめて分離した。

変更前(抜粋):

[api]
port = 54321
 
[db]
port = 54322
shadow_port = 54320
 
[db.pooler]
port = 54329
 
[studio]
port = 54323
 
[inbucket]
port = 54324
 
[edge_runtime]
inspector_port = 8083
 
[analytics]
port = 54327

変更後(2つ目プロジェクト用に 55320 番台へ):

[api]
port = 55321
 
[db]
port = 55322
shadow_port = 55320
 
[db.pooler]
port = 55329
 
[studio]
port = 55323
 
[inbucket]
port = 55324
 
[edge_runtime]
inspector_port = 8183
 
[analytics]
port = 55327

確認コマンド

grep -n "port\s*=\s*" supabase/config.toml

出力例(2つ目プロジェクト側):

10:port = 55321            # [api] APIサーバー
29:port = 55322            # [db] PostgreSQL
31:shadow_port = 55320     # [db] マイグレーション差分用シャドウDB
41:port = 55329            # [db.pooler] コネクションプーラー
87:port = 55323            # [studio] Supabase Studio(管理UI)
98:port = 55324            # [inbucket] メールテスト用Web UI
100:# smtp_port = 54325    # [inbucket] SMTP(コメントアウト)
101:# pop3_port = 54326    # [inbucket] POP3(コメントアウト)
219:# port = 587           # [auth.email.smtp] 本番用SMTP(コメントアウト)
360:inspector_port = 8183  # [edge_runtime] Chrome DevTools Inspector
369:port = 55327           # [analytics] ログ分析

コメントアウトされている行(smtp_portpop3_portauth.email.smtp)はデフォルトで無効。必要に応じて有効化する場合は、これらもプロジェクト間で重複しないようにずらす。

54320 番台と 55320 番台で分けると、後から見ても管理しやすい。

起動の目安

  1. 1つ目プロジェクトは既存ポート(54320 番台)
  2. 2つ目プロジェクトは変更後ポート(55320 番台)
  3. 各ディレクトリで supabase start を実行

成功時の出力

ポート変更後に supabase start が成功すると、以下のように各サービスのURLが 55320 番台で立ち上がる。

supabase local development setup is running.
 
╭──────────────────────────────────────╮
│ 🔧 Development Tools                 │
├─────────┬────────────────────────────┤
│ Studio  │ http://127.0.0.1:55323     │
│ Mailpit │ http://127.0.0.1:55324     │
│ MCP     │ http://127.0.0.1:55321/mcp │
╰─────────┴────────────────────────────╯
 
╭──────────────────────────────────────────────────────╮
│ 🌐 APIs                                              │
├────────────────┬─────────────────────────────────────┤
│ Project URL    │ http://127.0.0.1:55321              │
│ REST           │ http://127.0.0.1:55321/rest/v1      │
│ GraphQL        │ http://127.0.0.1:55321/graphql/v1   │
│ Edge Functions │ http://127.0.0.1:55321/functions/v1 │
╰────────────────┴─────────────────────────────────────╯
 
╭───────────────────────────────────────────────────────────────╮
│ ⛁ Database                                                    │
├─────┬─────────────────────────────────────────────────────────┤
│ URL │ postgresql://postgres:postgres@127.0.0.1:55322/postgres │
╰─────┴─────────────────────────────────────────────────────────╯

すべてのURLが 55320 番台になっていれば、1つ目プロジェクト(54320 番台)と競合せず共存できている。

まとめ

2つのSupabaseプロジェクトを同時に開発したい場合、supabase/config.toml のポートを体系的に分離すれば同時起動できる。 ポイントは「db.port だけでなく周辺ポートもまとめてずらす」こと。 今回は supabase start 時の 54322 競合エラーをきっかけにポート帯分離を行い、2プロジェクトの並行開発環境を整えた。