sbarbase
Contents

Move a project from Supabase

One command copies a Supabase project (Cloud or self-hosted) into a new Sbarbase environment: tables, row level security, users with their passwords, and Storage files. Your application keeps using supabase-js; only the address and the key change.

1. Check first

From the Supabase dashboard, open Connect and copy the Session pooler or direct connection string with your database password. Then, on the Sbarbase server:

python3 lab/import_project.py <environment> --dry-run <<'JSON'
{"database_url": "postgresql://postgres.<ref>:<db password>@aws-0-<region>.pooler.supabase.com:5432/postgres"}
JSON

It reads the project without changing anything and lists what stops the import (for example Vault secrets, or an extension this server does not have), what behaves differently, and what you will set again by hand.

2. Import

Create a new, empty environment in the console, then run the same command without --dry-run, adding the project's API address and its service_role key (Project Settings, API) so the Storage files can be copied:

python3 lab/import_project.py <environment> --report import-report.json <<'JSON'
{"database_url": "postgresql://postgres.<ref>:<db password>@aws-0-<region>.pooler.supabase.com:5432/postgres",
 "api_url": "https://<ref>.supabase.co", "service_role_key": "<service_role key>"}
JSON

Settings are read from stdin, never from the command line, so passwords appear in no process list. The source is only read.

What moves, in order:

  1. The public schema: tables, views, functions, policies and your own triggers, with the grants the source gave anon, authenticated and service_role, and no more.
  2. Users and their sign-in identities with password hashes: people sign in with their old passwords.
  3. Every row in public.
  4. Buckets, then every file, with its owner, so Storage policies on owner_id keep working.
  5. Your triggers on auth.users and storage.objects (for example "create a profile at sign-up"), recreated after the rows so they do not run again for imported users.
  6. A comparison of row counts, users, identities, buckets and files, source against target. The import only reports success when they all match.

3. Point your application at Sbarbase

  1. Create a publishable key on the environment's page.
  2. Replace the Supabase URL and anon key in your application with the environment's address and the new key.
  3. Set again what lives outside the database: sign-in settings and OAuth providers, email, Edge Functions (deploy the same supabase/functions folder), Realtime.

People sign in again once: sessions do not move. Everything else, including their passwords, does.

CI runs an import on a clean machine with every change, from another environment standing in for a Supabase project: the user signs in with the old password, reads only their own row, downloads their own private file, a new sign-up runs the imported trigger, and a second import into the full environment is refused (evidence). It is not a run against Supabase Cloud.

Limits

Edit on GitHub