new·The score now tells you which way it movedA brain's exam only ever grows: its own material writes questions, and so does every question a real caller asked and did not get answered. The score is a percentage over that growing set, so a brain that learned more could post a smaller number — and this week three did. One of them answered two MORE questions than the week before and showed eighteen points less. Printed as a single percentage, that reads as decline to a reader and as punishment to anyone who contributes material.all news →
mozg.beta
Sign in

Supabase · all subjects

self-hosted & deployment

182 notes in this subject, read out of this brain and free to use. This is page 1 of 4.

Features unavailable in self-hosted Supabase

The following features are unavailable in self-hosted Supabase compared to the managed platform: branching, advanced metrics beyond logs, managed backups and PITR, analytics and vector buckets, ETL, and the platform management API.

Self-hosted Supabase runs as single project

Self-hosted Supabase runs as a single project, which means that Studio does not support multiple organizations or projects. Most settings are configured through environment variables.

Supabase CLI collects telemetry

The Supabase CLI, a separate tool used for local development and other purposes, collects usage telemetry to help improve the developer experience. CLI telemetry can be opted out.

Use Docker for self-hosting Supabase

To self-host Supabase, use Docker or one of the community deployment options. Docker is a recommended approach for production self-hosted deployments.

Administrator responsibilities for self-hosted Supabase

When you self-host Supabase, you are responsible for: server provisioning and maintenance, security hardening and keeping OS and services updated, service configuration and management, Postgres database maintenance, high availability and scalability, backups and disaster recovery, and monitoring and uptime.

Self-hosted Supabase is community-supported

Self-hosted Supabase is community-supported, not directly supported by Supabase.

Self-hosted Supabase Docker telemetry

Self-hosted Supabase run via Docker Compose does not phone home or collect any telemetry.

Self-hosted Supabase is different from local development

Supabase CLI runs a local stack for development and testing that is not a self-hosted deployment. The local stack is not hardened for production and must not be exposed to external traffic. To self-host, use Docker or one of the community deployment options.

Platform Kit: embedded dashboard components

Platform Kit is a collection of UI components that interact with the Management API, serving as a lightweight version of the Supabase Dashboard. It can be embedded directly in your app to let users interact with their project without leaving your application. Documentation available at https://supabase.com/library/docs/platform/platform-kit.

Nano compute instance scale-to-zero pricing access

Only select customers have access to scale-to-zero pricing on Nano instances. Access requires submitting a form to the partnerships team at /solutions/ai-builders#talk-to-partnerships-team.

Remove custom configuration before transferring project

Before transferring a project to a user's org via project claim flow, remove any custom configuration that should not be retained by the user's project.

Example: Run security advisor

curl https://api.supabase.com/v1/projects/{ref}/advisors/security --request GET --header 'Authorization: Bearer {PAT_OR_USER_TOKEN}' --header 'Content-Type: application/json'

API keys migration: publishable and secret keys

Supabase is migrating from legacy API keys (anon and service_role) to new API keys (publishable and secret). Use GET /v1/projects/{ref}/api-keys to retrieve keys with reveal=true parameter. If publishable and secret keys exist, use only those. Otherwise, enable them by making POST /v1/projects/{ref}/api-keys requests for each type: one for 'publishable' and one for 'secret' with secret_jwt_template containing role 'service_role'.

Change compute instance size

Use PATCH /v1/projects/{ref}/billing/addons to upgrade or downgrade compute sizes. Request body requires addon_type: 'compute_instance' and addon_variant (e.g., 'ci_small').

Merge branch changes to production

Use POST /v1/branches/{ref}/merge to merge changes from a DEV branch to production. This automatically merges only database changes and deployed Edge Functions, not configuration or other changes.

Supabase as a platform: primitives offered

Supabase can be used as a Platform as a Service (PaaS) to offer key primitives to your own users, including Database, Auth, Edge Functions, Storage, and Realtime. All features can be managed programmatically through the Management API or the remote MCP Server.

Example: Restore database to point in time

curl https://api.supabase.com/v1/projects/database/backups/restore-pitr --request POST --header 'Authorization: Bearer {PAT_OR_USER_TOKEN}' --header 'Content-Type: application/json' --data '{"recovery_time_target_unix": 1}'

Management API: Create project endpoint

POST /v1/projects creates a new Supabase project. Required parameters: name, organization_slug, db_pass (database password), region_selection (object with type and code), and optional desired_instance_size. Smart region codes are 'americas', 'emea', and 'apac'. Do not pass desired_instance_size for Nano instances to enable scale-to-zero pricing. Micro and larger instances cannot scale to zero.

Project creation security recommendations

When creating projects programmatically: use a very secure and unique password for each database (do not reuse), store the encrypted version of the password, use smart region selection to ensure capacity, select appropriate instance size, and confirm all services reach ACTIVE_HEALTHY status before making service requests by polling GET /v1/projects/{ref}/health.

Create restore points for database changes

After every database change, create a restore point using POST /v1/projects/{ref}/database/backups/restore-point with a name parameter. This allows rolling back to that point if needed. Only select customers have access; submit form to /solutions/ai-builders#talk-to-partnerships-team. Note: only database changes are captured, not configuration or secrets.

Seed data best practices in DEV branches

Do not use production data in development branches, especially for non-developers. Use common test data instead to avoid security issues and unintended side effects like emailing production users. Insert seed data using POST /database/query endpoint.

Project claim flow for user ownership transfer

Use GET /v1/oauth/authorize/project-claim with project_ref, client_id, response_type, and redirect_uri to allow users to claim a project from the platform org. Users are redirected to a Supabase UI to create/select account and org, review permissions, confirm transfer, and then the project can be transferred to their org while retaining platform access via OAuth integration.

Database migrations endpoint requires special access

POST /v1/projects/{ref}/database/migrations allows creating and running database migrations. This endpoint automatically creates a migration inside the supabase_migrations schema and runs it. If the schema migration fails, changes are rolled back. Only select customers have access; submit form to /solutions/ai-builders#talk-to-partnerships-team.

Example: Create project via Management API

curl https://api.supabase.com/v1/projects --request POST --header "Content-Type: application/json" --header "Authorization: Bearer YOUR_SECRET_TOKEN" --data '{"name": "Todo App", "organization_slug": "aaaabbbbccccddddeeee", "db_pass": "SUPER_SECURE_PASSWORD", "region_selection": {"type": "smartGroup", "code": "americas"}, "desired_instance_size": "micro"}'

Security advisor for production deployment

Before deploying to production, run security checks using GET /v1/projects/{ref}/advisors/security to ensure the latest changes are secure.

Example: Create database migration

curl https://api.supabase.com/v1/projects/{ref}/database/migrations --request POST --header 'Authorization: Bearer YOUR_SECRET_TOKEN' --header 'Content-Type: application/json' --data '{"query": "create table public.todos (id serial primary key, task text not null); grant select on public.todos to anon; grant select, insert, update, delete on public.todos to authenticated; grant select, insert, update, delete on public.todos to service_role; alter table public.todos enable row level security;", "name": "Create a todos table"}'

Create a DEV branch for testing

Use POST /v1/projects/{ref}/branches to create a development branch named 'DEV'. Can include secrets in the request body as key-value pairs (e.g., STRIPE_SECRET_KEY). Branches are ephemeral and can be destroyed and recreated from production.

Debug projects using logs endpoint

Use GET /v1/projects/{ref}/analytics/endpoints/logs.all to query project logs and identify errors. The endpoint accepts sql parameter (SQL query), iso_timestamp_start, and iso_timestamp_end for filtering logs. Example: query edge_logs table with UNNEST for metadata and response to find status codes >= 400.

Example: Change compute instance size

curl 'https://api.supabase.com/v1/projects/{ref}/billing/addons' --request PATCH --header 'Content-Type: application/json' --header 'Authorization: Bearer YOUR_SECRET_TOKEN' --data '{"addon_type": "compute_instance", "addon_variant": "ci_small"}'

Example: Get API keys from project

curl 'https://api.supabase.com/v1/projects/{ref}/api-keys?reveal=true' --header 'Authorization: Bearer YOUR_SECRET_TOKEN'

Example: Enable secret API key

curl 'https://api.supabase.com/v1/projects/{ref}/api-keys?reveal=true' --request POST --header 'Content-Type: application/json' --header 'Authorization: Bearer YOUR_SECRET_TOKEN' --data '{"type": "secret", "name": "default", "secret_jwt_template": {"role": "service_role"}}'

Example: Enable publishable API key

curl 'https://api.supabase.com/v1/projects/{ref}/api-keys' --request POST --header 'Content-Type: application/json' --header 'Authorization: Bearer YOUR_SECRET_TOKEN' --data '{"type": "publishable", "name": "default"}'

Development workflow for stateful services

Supabase stores data and cannot roll back to a point in time without potentially causing data loss. Adopt a development workflow with a DEV branch where changes are tested before merging to production. This allows reverting or destroying the branch if anything goes wrong.

Example: Create DEV branch with secrets

curl 'https://api.supabase.com/v1/projects/{ref}/branches' --request POST --header 'Content-Type: application/json' --header 'Authorization: Bearer YOUR_SECRET_TOKEN' --data '{"branch_name": "DEV", "secrets": {"STRIPE_SECRET_KEY":"sk_test_123...", "STRIPE_PUBLISHABLE_KEY":"pk_test_123..."}}'

Configuration management endpoints

All Supabase services can be configured via Management API: Auth uses PATCH /v1/projects/{ref}/config/auth, Data API (PostgREST) uses PATCH /v1/projects/{ref}/postgrest, Edge Functions use PATCH /v1/projects/{ref}/functions/{function_slug} or PUT /v1/projects/{ref}/functions, Storage uses PATCH /v1/projects/{ref}/config/storage, and Realtime uses PATCH /v1/projects/{ref}/config/realtime.

Example: Revert to restore point

curl https://api.supabase.com/v1/projects/{ref}/database/backups/undo --request POST --header 'Authorization: Bearer YOUR_SECRET_TOKEN' --header 'Content-Type: application/json' --data '{"name": "abcdefg"}'

Example: Add seed data to table

curl https://api.supabase.com/v1/projects/{branch_ref}/database/query --request POST --header 'Authorization: Bearer YOUR_SECRET_TOKEN' --header 'Content-Type: application/json' --data '{"query": "insert into todos (task) values ('Task 1'), ('Task 2'), ('Task 3');"}'

Example: Merge branch to production

curl https://api.supabase.com/v1/branches/{ref}/merge --request POST --header 'Authorization: Bearer YOUR_SECRET_TOKEN' --header 'Content-Type: application/json' --data '{}'

Point-in-time recovery (PITR) for disaster recovery

Use POST /v1/projects/{ref}/database/backups/restore-pitr with recovery_time_target_unix parameter to restore a database to a specific point in time. Rollbacks can cause data loss and should only be used in production when absolutely necessary. Only available in prod when the project has explicitly enabled PITR prior to rolling back.

Example: Project claim flow OAuth redirect

curl -L "https://api.supabase.com/v1/oauth/authorize/project-claim?project_ref={ref}&client_id={oauth_client_id}&response_type=code&redirect_uri={redirect_uri}" --request GET --header 'Authorization: Bearer {PERSONAL_ACCESS_TOKEN}'

Example: Query project logs for errors

curl 'https://api.supabase.com/v1/projects/{ref}/analytics/endpoints/logs.all' --get --header 'Authorization: Bearer YOUR_SECRET_TOKEN' --data-urlencode 'sql=SELECT datetime(timestamp), status_code, path, event_message FROM edge_logs CROSS JOIN UNNEST(metadata) AS metadata CROSS JOIN UNNEST(response) AS response WHERE status_code >= 400 ORDER BY timestamp DESC LIMIT 100' --data-urlencode 'iso_timestamp_start=2025-03-23T00:00:00Z' --data-urlencode 'iso_timestamp_end=2025-03-23T01:00:00Z'

Reverting database changes to a restore point

Use POST /v1/projects/{ref}/database/backups/undo with a restore point name to revert all database changes since that point. This will undo schema changes, seed data, test users, and storage pointers. It will NOT affect configuration changes, secrets, storage objects, or deployed Edge Functions.

Verify storage copy with object count comparison

Compare object counts between source and destination using: rclone size platform:your-storage-bucket && rclone size self-hosted:your-storage-bucket. Open Studio on the self-hosted instance and browse the storage buckets to confirm files are accessible.

Optimize rclone performance for large migrations

For large migrations, consider adding --transfers 4 to increase parallelism, or --checkers 8 to speed up the comparison phase. For very large files, increase rclone's timeout with --timeout 30m

Prerequisites for copying storage objects with rclone

Before copying storage objects, you need: a working self-hosted Supabase instance with the S3 protocol endpoint enabled (see Configure S3 Storage), your platform project's S3 credentials from the S3 Configuration page, matching buckets created on your self-hosted instance, and rclone installed on the machine running the copy.

rclone configuration for copying storage objects S3-to-S3

To copy storage objects from a managed Supabase project to self-hosted using rclone, create or edit ~/.config/rclone/rclone.conf with two S3 remote configurations. For platform: type = s3, provider = Other, access_key_id = your-platform-access-key-id, secret_access_key = your-platform-secret-access-key, endpoint = https://your-project-ref.supabase.co/storage/v1/s3, region = your-project-region. For self-hosted: type = s3, provider = Other, access_key_id = your-self-hosted-access-key-id, secret_access_key = your-self-hosted-secret-access-key, endpoint = http://your-domain:8000/storage/v1/s3, region = your-self-hosted-region. For self-hosted, use the REGION, S3_PROTOCOL_ACCESS_KEY_ID and S3_PROTOCOL_ACCESS_KEY_SECRET from your S3 storage configuration.

Troubleshoot empty listing from platform in rclone

If rclone lsd platform: returns nothing, verify the endpoint URL ends with /storage/v1/s3 and that the S3 access keys have not expired. Regenerate them from the dashboard if needed.

Fix SignatureDoesNotMatch errors in rclone

If you see SignatureDoesNotMatch when connecting to either remote: For Platform, regenerate S3 access keys from the project's Storage Settings and ensure the endpoint URL includes /storage/v1/s3. For Self-hosted, verify that REGION, S3_PROTOCOL_ACCESS_KEY_ID and S3_PROTOCOL_ACCESS_KEY_SECRET in the .env file match your rclone config.

Copy all buckets with rclone in loop

To copy all buckets from platform to self-hosted: for bucket in $(rclone lsf platform: | tr -d '/'); do echo "Copying bucket: $bucket"; rclone copy "platform:$bucket" "self-hosted:$bucket" --progress; done

Copy single bucket with rclone

To copy a single bucket from platform to self-hosted: rclone copy platform:your-storage-bucket self-hosted:your-storage-bucket --progress

Verify rclone remotes can connect

After configuring rclone, verify both remotes connect by running: rclone lsd platform: and rclone lsd self-hosted: Both commands should list your buckets.

Get platform S3 credentials for storage transfer

In the managed Supabase project dashboard, go to Storage > S3 Configuration > Access keys. Generate a new access key pair and copy the Endpoint (https://<project-ref>.supabase.co/storage/v1/s3 or the direct hostname https://<project-ref>.storage.supabase.co/storage/v1/s3 for better performance with large files), Region (your project's region, e.g., us-east-1), Access Key ID, and Secret access key.

Configure MCP client to access self-hosted MCP server

Edit your MCP client settings and add the following JSON to the mcpServers or servers object: {"supabase-self-hosted": {"url": "http://localhost:8080/mcp"}}. This points the client to the MCP server accessed via the SSH tunnel.

Enable MCP access via Kong configuration

To allow MCP access via Kong, edit `./volumes/api/kong.yml`. Comment out the request-termination section. Uncomment the entire cors and ip-restriction section including `deny: []`. Add your local IPs to the allow list in the ip-restriction config. Preserve YAML indentation exactly as the config will fail to load if it changes.

Enable MCP access via Envoy configuration

To allow MCP access via Envoy, edit `./volumes/api/envoy/lds.template.yaml`. Find the route with `prefix: /mcp`. Comment out the rbac block that denies all traffic. Uncomment the allow-list policy and add your Docker bridge gateway IP to the principals list with `address_prefix` set to your gateway IP and `prefix_len: 32`. Keep loopback entries (127.0.0.1 and ::1). Preserve YAML indentation exactly as the config will fail to load if it changes.

Determine Docker bridge gateway IP for MCP access

To allow SSH tunnel access to the MCP server, determine the Docker bridge gateway IP using the command: For Envoy: `docker inspect supabase-envoy --format '{{range .NetworkSettings.Networks}}{{println .Gateway}}{{end}}'`. For Kong: `docker inspect supabase-kong --format '{{range .NetworkSettings.Networks}}{{println .Gateway}}{{end}}'`. This IP (e.g., 172.18.0.1) will be the source IP when connecting via SSH tunnel.

MCP server access must be restricted to internal connections only

Do not allow connections to the self-hosted MCP server from the Internet. Only access it via a VPN connection to the server running the Studio container or an SSH tunnel from your local machine.

Create SSH tunnel to access self-hosted MCP server

From your local machine, create an SSH tunnel with the command: `ssh -L localhost:8080:localhost:8000 you@your-supabase-host`. This forwards local port 8080 to port 8000 on your Supabase host.

MCP server does not support OAuth 2.1 authentication

The MCP (Model Context Protocol) server in self-hosted Supabase does not currently offer OAuth 2.1 authentication. It is not intended to be exposed to the Internet and all connections are denied by default.

Restart API gateway after MCP configuration changes

After adding local IP addresses to the Envoy or Kong configuration, restart the API gateway using the command: `sh run.sh restart api-gw`.

Give your agent this brain