Migrate from Supabase
Move a Supabase project's database, users, and files to Clouzark with one command.
clouzark import supabase copies a Supabase project into a new Clouzark database. Your app then switches by changing two values, its URL and anon key, because supabase-js works against Clouzark.
export SUPABASE_DB_URL='postgresql://postgres.<ref>:<password>@aws-0-<region>.pooler.supabase.com:5432/postgres'
export SUPABASE_URL='https://<ref>.supabase.co' # optional, to copy storage
export SUPABASE_SERVICE_ROLE_KEY='<service_role key>' # optional, to copy storage
clouzark import supabase --dry-run # inspect and report, change nothing
clouzark import supabase --name my-appIn the dashboard: on the Databases page, Import from Supabase. Paste the connection string (and the project URL and service key to copy files), review the report, name the new database, and import.
Get the connection string in Supabase under Connect (Session pooler or Direct). It includes your database password. Without the env vars, the command asks for each value without echoing it. The credentials are sent to Clouzark for this import only and are never stored.
What's copied
| From Supabase | To Clouzark |
|---|---|
Your schemas (public and any you created), with tables, data, views, functions, triggers, and indexes | The new database. Other schemas than public are copied but not exposed to the APIs until you add them under Settings → Exposed schemas |
Extensions in the extensions schema (for example uuid-ossp, pgcrypto) | Created again where this server has them |
| Auth users, with the same ids and password hashes | Auth: users sign in with their existing passwords |
| OAuth identities (GitHub, Google) | Kept; set up the same provider under Auth settings |
| Row-level security policies, including storage ones | Recreated. TO authenticated becomes auth.uid() IS NOT NULL, TO anon becomes auth.uid() IS NULL, and policies only for service_role are dropped, since the service key bypasses RLS here too |
Triggers on auth.users (such as handle_new_user) | Recreated on Clouzark's auth.users |
| Storage buckets and files | Storage; bucket names become lowercase with hyphens |
auth.uid(), auth.jwt(), auth.role(), and auth.email() all exist, so policies and functions that use them keep working.
What isn't
- Edge functions: run server code in a Clouzark-hosted app and link the database to it.
pg_cronjobs: recreate them as cron jobs.pg_netcalls and realtimepostgres_changessubscriptions.- Files over 100 MB.
Users without an email (anonymous or phone sign-in) are copied with a placeholder email so their rows stay linked, but can't sign in until they have a real one. The report at the end lists everything that needs attention.
After the import
- Replace your Supabase URL and anon key with the values the command prints (also in
clouzark db keys). - If the app runs on Clouzark, link the database to it with
clouzark projects database linkso it gets them as env vars. - Set up OAuth providers and email settings under Auth if you use them.