Repository navigation
Come Home Supabase
Start a fresh nSelf project before importing, with AUTH_ENABLED=true and, if the
project has storage objects, an object store (MinIO or SeaweedFS). Postgres and Hasura
must be healthy. The source must run PostgreSQL 12 or later, with a major no newer than
the target (set POSTGRES_VERSION in the target first if needed).
- The direct database connection string (Project Settings > Database > Connection string, "Direct connection"; use the pooler URL only if your plan has no direct connection, and note that a pooler cannot hold the repeatable-read snapshot the import needs). Put it in an environment variable. The URL must not appear in a command argument or shell history.
- For storage: the API URL (
https://<project-ref>.supabase.co, or--project-ref) and theservice_rolekey, again in an environment variable.
nself db import supabase --db-url-env SUPA_DB --project-ref abcdefghijkl --service-key-env SUPA_KEY --plan --json
nself db import supabase --db-url-env SUPA_DB --project-ref abcdefghijkl --service-key-env SUPA_KEY --jsonIn v1.4 mode the command is nself migrate supabase, which only writes migration
artifacts (see cmd-migrate-supabase). In v1.5 mode it imports and verifies. The plan
checks source and target and writes nothing. For a self-hosted or local Supabase use
--api-url http://127.0.0.1:<port> (plain http is accepted only for loopback hosts).
| Part | How | Notes |
|---|---|---|
| Your tables | One pg_dump snapshot, restored with pg_restore
|
Every schema except the Supabase-owned ones |
| Auth users |
auth.users to nSelf auth.users
|
encrypted_password is bcrypt and is kept, so users sign in with the password they have today. Every user gets the allowed role user
|
| Storage | Storage REST API with the service key | Each bucket and object; the object count must match storage.objects
|
| Access rules (RLS) | Translated or listed | See below |
Excluded schemas: auth, storage, realtime, supabase_functions, extensions,
graphql, graphql_public, pgbouncer, pgsodium, vault, net,
supabase_migrations. The Supabase roles (anon, authenticated, service_role) are
never recreated, and ownership and grants are not restored.
Row level security policies and the ENABLE ROW LEVEL SECURITY switch are not
restored. A policy of the form auth.uid() = <column> (either order) on a permissive
policy for authenticated or public becomes a Hasura permission for the user role:
select, update and delete filter on {"<column>": {"_eq": "X-Hasura-User-Id"}},
insert checks it. Several policies for one command are combined with _or.
A translated permission covers only the kinds that the role authenticated can use on the table
(it needs the privilege), and a read command needs a USING expression. A table with a
restrictive policy has none of its policies translated, because Hasura has no AND rule and
would grant more than Postgres did.
Every other policy (restrictive policies, other roles, any other expression) is listed
in the report under untranslated_policies with its text and the reason. Hasura denies
a role that has no permission, so an untranslated policy means that access is closed
for non-admin roles until you add a Hasura permission for it. Review that list before
you open the app to users. The admin secret bypasses permissions.
The bundle carries db/compat.sql, listed in the report as compat_shims:
-
extensions.uuid_generate_v4()andextensions.gen_random_uuid()become wrappers for Postgresgen_random_uuid(), so column defaults keep working. -
auth.uid()readsx-hasura-user-idfrom the session settinghasura.user, so a default ofauth.uid()fills the owner column with the caller's id when a user inserts through Hasura.
Other extensions.* or auth.* functions that your schema calls have no shim. They are
listed as exemptions (compat:<name>); define them in the target before relying on them.
- Partitioned tables are refused. Foreign keys into Supabase-owned tables other than
auth.users(for examplestorage.objects) are not supported. - A bucket name that the object store rejects (uppercase or underscore, for example
user_uploads) stops the import with a clear message in this version. Supabase cannot rename a bucket, so create a new bucket with a valid name, copy the objects, delete the old bucket and repeat the import.--skip-storagedoes not bypass the check. - Policies on Supabase-owned tables (for example
storage.objectsrules) and user triggers onauth.usersorstorage.objects(for example a profile trigger) are not moved. They are listed in the report (untranslated_policies, and exemptionstrigger:<table>#<name>); recreate them. A schema with triggers that call Supabase-owned functions (database webhooks:supabase_functions.http_request) is refused before anything is written. - Users whose email differs only by case, or whose phone repeats, are refused before anything is
written (hasura-auth keeps both unique). Soft-deleted users (
deleted_at) and users with a ban in the future are imported as disabled; a dated ban becomes a plain disabled flag. - The shim
auth.uid()reads the session Hasura sets for mutations. It serves column defaults on insert; use Hasura permissions for access rules. - After a failed import the private stage under
.nself/import/<run-id>/keeps the user hashes (mode 0700); delete it once you no longer need it. - A user whose hash is not bcrypt is listed in
users.reset_required. - Bucket settings (public flag, size limit, allowed types) are not carried; set them in the
target.
auth.identitiesis not carried, so a user who only signed in through an OAuth provider has no password on the target (hash algorithmnone). - The snapshot and the storage listing are read at slightly different moments. If someone uploads or deletes an object during the import, the count check stops it ("storage listing differs from the storage catalog"); rerun on a quiet source.
- A schema that uses
extensions.*functions or types without a shim (for examplecrypt,digest,citext,vector) lists them as exemptions and the restore stops where it needs them. Install the extension in the target first. - Edge functions, realtime and cron jobs are not moved. Row level security stays off in the target
(the
ENABLE ROW LEVEL SECURITYswitch is not restored); access is governed by Hasura permissions.
The result appears in the JSON envelope and in .nself/import/<run-id>/report.json. A
pass means every non-exempt row count, content hash, user hash algorithm, object
checksum, tracking record, permission and independent source count matched. After a
failed import see Come-Home-Postgres for the reset sequence (wrote and last_step
in the report):
nself db reset --yes← Leaving-nSelf | Home →
Getting Started
Commands
- Commands, Overview
- Lifecycle: cmd-init · cmd-build · cmd-start · cmd-stop · cmd-restart · cmd-dev
- Monitoring: cmd-status · cmd-logs · cmd-health · cmd-urls · cmd-doctor · cmd-monitor · cmd-alerts · cmd-sentry · cmd-watchdog
- Data: cmd-db · cmd-backup · cmd-dr · cmd-queue · cmd-webhooks
- Config: cmd-config · cmd-service · cmd-env · cmd-promote
- Networking: cmd-ssl · cmd-trust · cmd-dns-setup
- Security: cmd-access · cmd-security · cmd-secrets
- Tenancy: cmd-tenant · cmd-billing
- Plugins: cmd-plugin · cmd-license · cmd-dogfood (extracted, CLI-R11) · cmd-k8s (extracted, CLI-R11) · cmd-encryption (extracted, CLI-R11) · cmd-waf (extracted, CLI-R11) · cmd-federation (extracted, CLI-R11) · cmd-mail (extracted, CLI-R11) · cmd-dlq (extracted, CLI-R11)
- AI: cmd-ai · cmd-claw · cmd-model
- Templates: cmd-template
- Utilities: cmd-exec · cmd-clean · cmd-reset · cmd-update · cmd-upgrade · cmd-version · cmd-admin · cmd-migrate · cmd-migrate-firebase · cmd-migrate-supabase · cmd-completion
Features
- Features, Overview
- Feature-Auth
- Feature-Storage
- Feature-Search
- Feature-Functions
- Feature-Email
- Feature-Monitoring
- Feature-Plugins
- Feature-nClaw, AI Assistant
- Feature-nChat, Messaging
- Feature-nFamily, Family Social
- Feature-nCloud, Managed Hosting
- Feature-Memory-Rooms, Knowledge Organization
- Feature-Agent-Dashboard, Agent Metrics
- Feature-Image-Generation, AI Image Generation
Configuration
- Configuration, Overview
- Config-Env-Vars
- Config-Postgres
- Config-Hasura
- Config-Auth
- Config-Nginx
- Shared-Proxy
- Config-Optional-Services
- Config-Custom-Services
- Config-System
Plugins (87 + 10 monitoring)
- Plugin-Overview
- Plugin-Catalog
- Plugin-Install
- Plugin-Licensing
- Plugin-Architecture
- Plugin-Dev-Guide
- Plugin-Migrations-Contract
Free (25)
- plugin-backup
- plugin-content-acquisition
- plugin-content-progress
- plugin-cron
- plugin-donorbox
- plugin-feature-flags
- plugin-github
- plugin-github-runner
- plugin-invitations
- plugin-jobs
- plugin-link-preview
- plugin-mdns
- plugin-mlflow
- plugin-monitoring
- plugin-notifications
- plugin-notify
- plugin-paypal
- plugin-search
- plugin-shopify
- plugin-stripe
- plugin-subtitle-manager
- plugin-tokens
- plugin-torrent-manager
- plugin-vpn
- plugin-webhooks
Pro (62)
- plugin-access-controls
- plugin-activity-feed
- plugin-admin-api
- plugin-analytics
- plugin-auth
- plugin-bots
- plugin-browser
- plugin-calendar
- plugin-cdn
- plugin-chat
- plugin-claw
- plugin-claw-budget
- plugin-claw-news
- plugin-claw-web
- plugin-cloudflare
- plugin-cms
- plugin-compliance
- plugin-ddns
- plugin-devices
- plugin-documents
- plugin-entitlements
- plugin-file-processing
- plugin-game-metadata
- plugin-geocoding
- plugin-geolocation
- plugin-google
- plugin-home
- plugin-idme
- plugin-knowledge-base
- plugin-linkedin
- plugin-livekit
- plugin-media-processing
- plugin-meetings
- plugin-moderation
- plugin-mux
- plugin-object-storage
- plugin-observability
- plugin-photos
- plugin-podcast
- plugin-post
- plugin-realtime
- plugin-retro-gaming
- plugin-rom-discovery
- plugin-social
- plugin-sports
- plugin-support
- plugin-tmdb
- plugin-voice
- plugin-web3
- plugin-workflows
Planned (26)
plugin-auditplugin-blogplugin-checkoutplugin-commerceplugin-drmplugin-exportplugin-flowplugin-importplugin-ldapplugin-mailgunplugin-mediaplugin-oauth-providersplugin-pagesplugin-postmarkplugin-rate-limitplugin-reportsplugin-samlplugin-schedulerplugin-sendgridplugin-ssoplugin-subscriptionplugin-thumbplugin-transcoderplugin-twilioplugin-wafplugin-watermark
Guides
- Guide-Production-Deployment
- Guide-SSL-Setup
- Guide-Multi-Tenancy
- Guide-Security-Hardening
- Guide-Monitoring-Setup
- Guide-Backup-Restore
- Guide-Custom-Services
- Guide-Migration-from-v1
Architecture
- Architecture
- Architecture-Guardrails
- Service-Graph
- Compose-Generation
- Nginx-Generation
- Plugin-Architecture
Reference
Machine interface
-
JSON-Output,
--jsonenvelope -
Command-Registry,
nself help --json - Exit-Codes
- error-codes, Error Codes
-
Compat-V15,
NSELF_V15gate
Licensing
Security
Brand
Operations
- operations/release-cascade, Release Cascade
- operations/self-healing, Self-Healing Schema
- operations/redis-tuning, Redis Pool Tuning
- operations/meilisearch-warmup, MeiliSearch Warm-Up
- operations/jwt-rotation, JWT Key Rotation
- operations/windows-wsl2-setup, Windows / WSL2 Setup
- operations/gemini-oauth-reauth, Gemini OAuth Reauth
Contributing
Admin
- USER-ACTION-QUEUE, Pending Admin Actions
All commands (21)
- A: cmd-add · cmd-admin
- B: cmd-backup · cmd-build
- C: cmd-clean · cmd-config
- D: cmd-db · cmd-deploy · cmd-doctor
- E: cmd-exec
- I: cmd-init
- L: cmd-license · cmd-logs
- M: cmd-mcp
- R: cmd-remove · cmd-reset · cmd-restart
- S: cmd-start · cmd-status · cmd-stop
- U: cmd-update