Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apps/docs/components/HomePageCover.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ const HomePageCover = (props) => {
tooltip: 'TanStack Start',
icon: '/docs/img/icons/tanstack-icon',
href: '/guides/getting-started/quickstarts/tanstack',
hasLightIcon: false,
hasLightIcon: true,
},
{
tooltip: 'Vue',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2827,6 +2827,7 @@ export const self_hosting: NavMenuConstant = {
items: [
{ name: 'Overview', url: '/guides/self-hosting' },
{ name: 'Self-Hosting with Docker', url: '/guides/self-hosting/docker' },
{ name: 'Restore from Platform', url: '/guides/self-hosting/restore-from-platform' },
{
name: 'Configuration',
items: [{ name: 'Enabling MCP server', url: '/guides/self-hosting/enable-mcp' }],
Expand Down
4 changes: 4 additions & 0 deletions apps/docs/content/errorCodes/realtimeErrorCodes.toml
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ description = "The rate of joins per second from your clients has reached the ch

[RealtimeDisabledForTenant]
description = "Realtime has been disabled for the tenant."
resolution = "Your project may have been suspended for exceeding usage quotas. Contact support with your project reference ID and a description of your Realtime use case."
[[RealtimeDisabledForTenant.references]]
href = "https://supabase.com/docs/troubleshooting/realtime-project-suspended-for-exceeding-quotas"
description = "Troubleshooting guide for suspended projects"

[UnableToConnectToTenantDatabase]
description = "Realtime was not able to connect to the tenant's database."
Expand Down
9 changes: 9 additions & 0 deletions apps/docs/content/guides/getting-started.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,15 @@ hideToc: true
icon: '/docs/img/icons/vuejs-icon',
enabled: isFeatureEnabled('docs:framework_quickstarts'),
},
{
title: 'TanStack Start',
href: '/guides/getting-started/quickstarts/tanstack',
description:
'Learn how to create a Supabase project, add some sample data to your database, and query the data from a TanStack Start app.',
icon: '/docs/img/icons/tanstack-icon',
hasLightIcon: true,
enabled: isFeatureEnabled('docs:framework_quickstarts'),
},
{
title: 'Refine',
href: '/guides/getting-started/quickstarts/refine',
Expand Down
14 changes: 14 additions & 0 deletions apps/docs/content/guides/platform/sso.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,20 @@ When SSO is enabled for an organization:
- If an SSO user with the following email of `alice@foocorp.com` attempts to sign in with a GitHub account that uses the same email, a separate Supabase account is created and will not be linked to the SSO user's account.
- SSO users will only see organizations/projects they've been invited to or auto-joined into. See [access control](/docs/guides/platform/access-control) for more details.

## Enabling SSO for an organization

- Review the steps above to configure your setup.
- Invite users to the organization and ensure they join with their SSO linked account.
- If a user is already a member of the organization under a non SSO account, they will need to be removed and invited again for them to join under their SSO account.

<Admonition type="note">

**No automatic linking:** Each user account verified using a SSO identity provider will not be automatically linked to existing user accounts in the system. That is, if a user `valid.email@supabase.io` had signed up with a password, and then uses their company SSO login with your project, there will be two `valid.email@supabase.io` user accounts in the system.

Users will need to ensure they are logged in with the correct account when accepting invites or accessing organizations/projects.

</Admonition>

## Disabling SSO for an organization

If you disable the SSO provider for an organization, **all SSO users will immediately be unable to sign in**. Before disabling SSO, ensure you have at least one non-SSO owner account to prevent being locked out.
Expand Down
5 changes: 2 additions & 3 deletions apps/docs/content/guides/self-hosting.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ The fastest and recommended way to self-host Supabase is using Docker.
</div>
</div>

## Other deployment options
## Community-driven projects

{/* supa-mdx-lint-disable-next-line Rule004ExcludeWords */}
There are several other ways to deploy Supabase with the help of community-driven projects. These projects may be outdated and are seeking active maintainers. If you're interested in maintaining one of these projects, [contact the Community team](/open-source/contributing/supasquad).
There are several other options to deploy Supabase. If you're interested in helping these projects, visit our [Community](/contribute) page.

<div className="grid md:grid-cols-12 gap-4 not-prose">
{selfHostingCommunity.map((x) => (
Expand All @@ -41,7 +41,6 @@ There are several other ways to deploy Supabase with the help of community-drive
title={
<span className="flex items-center gap-2">
{x.name}
<Badge>Maintainer needed</Badge>
</span>
}
>
Expand Down
4 changes: 2 additions & 2 deletions apps/docs/content/guides/self-hosting/docker.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ This guide assumes you're comfortable with:
- Docker and Docker Compose
- Networking fundamentals (ports, DNS, firewalls)

If you're new to these topics, consider starting with [managed Supabase](/dashboard) for free, or try [local development with the CLI](/docs/guides/local-development).
If you're new to these topics, consider starting with managed [Supabase platform](/dashboard) for free.

You need the following installed on your system:

Expand Down Expand Up @@ -147,7 +147,7 @@ sh ./utils/generate-keys.sh

The script is experimental, so review the output before proceeding and also check `.env` after it's updated by the script.

Alternatively, configure all secrets manually as follows.
**Alternatively, configure all secrets manually as follows.**

### Configure database password

Expand Down
180 changes: 180 additions & 0 deletions apps/docs/content/guides/self-hosting/restore-from-platform.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
---
title: 'Restore a Platform Project to Self-Hosted'
description: 'Restore your database from the Supabase platform to a self-hosted instance.'
subtitle: 'Restore your database from the Supabase platform to a self-hosted instance.'
---

This guide walks you through restoring your database from a Supabase platform project to a [self-hosted Docker instance](/docs/guides/self-hosting/docker). Storage objects transfer or redeploying edge functions is not covered here.

## Before you begin

You need:

- A new self-hosted Supabase instance ([Docker setup guide](/docs/guides/self-hosting/docker))
- [Supabase CLI](/docs/guides/local-development/cli/getting-started) installed (or use `npx supabase`)
- [Docker Desktop](https://docs.docker.com/get-started/get-docker/) installed (required by the CLI)
- `psql` installed ([official installation guide](https://www.postgresql.org/download/))
- Your Supabase database passwords (for platform and self-hosted)

## Step 1: Get your platform connection string

On your managed Supabase project dashboard, click [**Connect**](/dashboard/project/_?showConnect=true) and copy the connection string (use the session pooler or direct connection).

## Step 2: Back up your platform database

Export roles, schema, and data as three separate SQL files:

```bash
supabase db dump --db-url "[CONNECTION_STRING]" -f roles.sql --role-only
```

```bash
supabase db dump --db-url "[CONNECTION_STRING]" -f schema.sql
```

```bash
supabase db dump --db-url "[CONNECTION_STRING]" -f data.sql --use-copy --data-only
```

This produces SQL files that are compatible across Postgres versions.

<Admonition type="note">

Using `supabase db dump` executes `pg_dump` under the hood but applies Supabase-specific filtering - it excludes internal schemas, strips reserved roles, and adds idempotent `IF NOT EXISTS` clauses. Using raw `pg_dump` directly will include Supabase internals and cause permission errors during restore. CLI requires Docker because it runs `pg_dump` inside a container from the Supabase Postgres image rather than requiring a local Postgres installation.

</Admonition>

## Step 3: Prepare your self-hosted instance

Before restoring, check the following on your self-hosted instance:

- **Extensions**: Enable any non-default extensions your Supabase project uses. You can check which extensions are active by querying `select * from pg_extension;` on your managed database (or check Database Extensions in Dashboard).

## Step 4: Restore to your self-hosted database

Connect to your self-hosted Postgres and restore the dump files. The [default](/docs/guides/self-hosting/docker#accessing-postgres) connection string for self-hosted Supabase is:

```
postgres://postgres.your-tenant-id:[POSTGRES_PASSWORD]@[your-domain]:5432/postgres
```

Where `[POSTGRES_PASSWORD]` is the value of `POSTGRES_PASSWORD` in your self-hosted `.env` file.

Use your domain name, your server IP, or localhost for `[your-domain]` depending on whether you are running self-hosted Supabase on a VPS, or locally.

Run `psql` to restore:

```bash
psql \
--single-transaction \
--variable ON_ERROR_STOP=1 \
--file roles.sql \
--file schema.sql \
--command 'SET session_replication_role = replica' \
--file data.sql \
--dbname "postgres://postgres.your-tenant-id:[POSTGRES_PASSWORD]@[your-domain]:5432/postgres"
```

Setting `session_replication_role` to `replica` disables triggers during the data import, preventing issues like double-encryption of columns.

## Step 5: Verify the restore

Connect to your self-hosted database and run a few checks:

```bash
psql "postgres://postgres.your-tenant-id:[POSTGRES_PASSWORD]@[your-domain]:5432/postgres"
```

```sql
-- Check your tables are present
\dt public.*

-- Verify row counts on key tables
SELECT count(*) FROM auth.users;

-- Check extensions
SELECT * FROM pg_extension;
```

## What's included and what's not

The database dump includes your schema, data, roles, RLS policies, database functions, triggers, and `auth.users`. However, several things require separate configuration on your self-hosted instance:

| Requires manual setup | How to configure |
| --- | --- |
| JWT secrets and API keys | Generate new ones and update `.env` |
| Auth provider settings (OAuth, Apple, etc.) | Configure `GOTRUE_EXTERNAL_*` variables in `.env` |
| Edge functions | Manually copy to your self-hosted instance |
| Storage objects | Transfer separately (not covered in this guide) |
| SMTP / email settings | Configure `SMTP_*` variables in `.env` |
| Custom domains and DNS | Point your DNS to the self-hosted server |

## Auth considerations

Your `auth.users` table and related data are included in the database dump, so user accounts are preserved. However:

- **JWT secrets differ** between your platform and self-hosted instances. Existing tokens issued by the platform project will not be valid. Users will need to re-authenticate.
- **Social auth providers** (Apple, Google, GitHub, etc.) need to be configured in your self-hosted `.env` file. Set the relevant `GOTRUE_EXTERNAL_*` variables. See the Auth repository [README](https://github.com/supabase/auth) for all available options.
- **Redirect URLs** in your OAuth provider consoles (Apple Developer, Google Cloud Console, etc.) must be updated to point to your self-hosted hostname instead of `*.supabase.co`.

## Postgres version compatibility

Managed Supabase may run a newer Postgres version (Postgres 17) than the self-hosted Docker image (currently Postgres 15). The `supabase db dump` command produces plain SQL files that work across major Postgres versions.

Keep in mind:

- The data dump may include Postgres 17-only settings or reference tables/columns from newer Auth and Storage versions that don't exist on self-hosted yet. See [Version mismatches](#version-mismatches-between-platform-and-self-hosted) in the troubleshooting section.
- Run the restore on a test self-hosted instance first to identify any incompatibilities.
- Check that all extensions you use are available on the self-hosted Postgres version.

## Troubleshooting

### Version mismatches between platform and self-hosted

The platform may run a newer Postgres version (17 vs 15) and newer Auth service versions than self-hosted. The data dump can contain settings, tables, or columns that don't exist on your new self-hosted instance.

**Common issues in `data.sql`:**

- `SET transaction_timeout = 0` - a Postgres 17-only setting that fails on Postgres 15
- `COPY` statements for tables that don't exist on self-hosted (e.g., `auth.oauth_clients`, `storage.buckets_vectors`, `storage.vector_indexes`)
- `COPY` statements with columns added in newer Auth versions (e.g., `auth.flow_state` with `oauth_client_state_id`, `linking_target_id`)

**Workaround:** Edit `data.sql` before restoring:

```bash
# Comment out PG17-only transaction_timeout
sed -i 's/^SET transaction_timeout/-- &/' data.sql
```

For missing tables or column mismatches, comment out the relevant `COPY ... FROM stdin;` line and its corresponding `\.` terminator. Run the restore without `--single-transaction` first to identify all failures, then fix them and run the final restore with `--single-transaction`.

Keeping your self-hosted configuration [up to date](https://github.com/supabase/supabase/blob/master/docker/CHANGELOG.md) will minimize these gaps.

### Extension not available

If the restore fails because an extension isn't available, check whether it's supported on your self-hosted Postgres version. You can list available extensions with:

```sql
SELECT * FROM pg_available_extensions;
```

### Connection refused

Make sure your self-hosted Postgres port is accessible. In the default [self-hosted Supabase](/docs/guides/self-hosting/docker#accessing-postgres) setup, the user is `postgres.your-tenant-id` with Supavisor on port `5432`.

### Legacy Studio configuration

Studio in self-hosted Supabase historically used `supabase_admin` role (superuser) instead of `postgres`. Objects created via Studio UI were owned by `supabase_admin`. Check your `docker-compose.yml` [configuration](https://github.com/supabase/supabase/blob/2cb5befaa377a42b6d6ca152b98105b59054f2f4/docker/docker-compose.yml#L30) to see if `POSTGRES_USER_READ_WRITE` is set to `postgres`.

### Custom roles missing passwords

If you created custom database roles with the `LOGIN` attribute on your platform project, their passwords are not included in the dump. Set them manually after restore:

```sql
ALTER ROLE your_custom_role WITH PASSWORD 'new-password';
```

### Additional resources

- [Backup and Restore using the CLI](/docs/guides/platform/migrating-within-supabase/backup-restore)
- [Restore Dashboard backup](/docs/guides/platform/migrating-within-supabase/dashboard-restore)
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
title = "App Store Rejection: 'TLS error' in IPv6-only environments"
topics = [ "platform" ]
keywords = []
database_id = "ce8c04e4-d493-4e15-832a-e59bdcf2b093"
---

If your App Store submission is rejected with a 'TLS error' when tested in an IPv6-only environment, often citing a lack of AAAA records, it typically indicates application-level issues rather than a Supabase configuration problem.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@
title = "Auth Hooks: 'Invalid payload' when anonymous users attempt phone changes"
topics = [ "auth", "cli" ]
keywords = []
database_id = "c1de4561-e95f-41e3-b298-fac9ae331a54"

[[errors]]
http_status_code = 500
message = "Invalid payload sent to hook"

---

An 'Invalid payload sent to hook' error (500) occurs in Auth hooks when the payload includes `new_phone` for an anonymous user.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
title = "Autovacuum Stalled Due to Inactive Replication Slot"
topics = [ "database" ]
keywords = []
database_id = "a931b8af-3210-4188-bb03-87452923a498"
---

If you observe that `supabase inspect db vacuum-stats` reports "Expect autovacuum? yes" for your tables, but autovacuum activity has been inactive for an extended period, leading to increasing database RAM usage, this typically indicates a stalled autovacuum process. One of the reasons for autovacuum to get stalled is an inactive replication slot for which this guide talks about.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
title = "'Cloudflare Origin Error 1016' on Custom Domain"
topics = [ "platform" ]
keywords = []
database_id = "a60ee728-3add-438d-b8bf-433f1746cb3e"

[[errors]]
code = "1016"
message = "Cloudflare Origin Error"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ github_url = "https://github.com/orgs/supabase/discussions/16703"
date_created = "2023-08-22T13:17:50+00:00"
topics = ["database"]
keywords = ["rls", "deprecated", "auth", "policy"]
database_id = "58c0cb7c-50a0-4a96-9551-bc97c28b7393"
---

## The `auth.role()` function is now deprecated
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ github_url = "https://github.com/orgs/supabase/discussions/16784"
date_created = "2023-08-24T13:45:01+00:00"
topics = ["database"]
keywords = ["security", "function", "schema", "policy", "definer"]
database_id = "1e02e989-fc12-4838-b304-c7d1356f6d2c"
---

PostgREST supports 2 config parameters:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
title = "Edge Function 546 error response"
topics = [ "functions" ]
keywords = [ "546", "error", "resource", "memory", "cpu", "event loop", "edge function" ]
database_id = "4e6ff2e4-2abb-4fba-8233-5883b3d56fb0"

[[errors]]
http_status_code = 546
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
title = "Edge Function bundle size issues"
topics = [ "functions" ]
keywords = [ "bundle", "size", "limit", "dependencies", "edge function", "10MB" ]
database_id = "aaf9e673-64ae-460a-88e0-b83ea4963382"

[api]
cli = ["supabase-functions-deploy"]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
title = "Understanding Edge Function CPU limits"
topics = [ "functions" ]
keywords = [ "CPU", "limit", "isolate", "soft limit", "hard limit", "edge function" ]
database_id = "1765884f-81d6-415a-a78f-7085f7b7ddbf"
---

Learn how Edge Functions manage CPU resources and what happens when limits are reached.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
title = "Edge Function dependency analysis"
topics = [ "functions" ]
keywords = [ "dependencies", "npm", "deno", "imports", "bundle", "optimization", "edge function" ]
database_id = "e079a9d0-419a-4e31-b7ec-1206d9012d0b"
---

Optimize your Edge Function dependencies for better performance. Large or unnecessary dependencies can significantly impact bundle size, boot time, and memory usage.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
title = "Monitoring Edge Function resource usage"
topics = [ "functions" ]
keywords = [ "monitoring", "metrics", "CPU", "memory", "performance", "edge function" ]
database_id = "33e8e407-951b-4f7d-b8b4-8e9085cd4d10"
---

Learn how to track your Edge Function's performance and identify potential resource issues.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
title = "Edge Function shutdown reasons explained"
topics = [ "functions" ]
keywords = [ "shutdown", "termination", "event loop", "wall clock", "cpu time", "memory", "early drop" ]
database_id = "109b964f-c28c-4554-b059-cd8b165c63f8"

[[errors]]
http_status_code = 546
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
title = "Edge Function takes too long to respond"
topics = [ "functions" ]
keywords = [ "slow", "timeout", "performance", "boot", "response time", "edge function" ]
database_id = "89b868a9-17fe-4c6d-86f6-0b04e5794678"
---

Edge Functions have a 60-second execution limit. If your function is taking too long to respond, follow these steps to diagnose and optimize performance.
Expand Down
Loading
Loading