Skip to content
Self-Hosting

将平台项目恢复到自托管

Restore your database from the Supabase platform to a self-hosted instance.

本指南将引导你将数据库从 Supabase 平台项目恢复到 自托管的 Docker 实例。这里不涉及传输存储对象或重新部署 edge 函数。

🌐 This guide walks you through restoring your database from a Supabase platform project to a self-hosted Docker instance. Transferring storage objects or redeploying edge functions is not covered here.

在你开始之前 #

🌐 Before you begin

你需要:

🌐 You need:

步骤1:获取你的平台连接字符串 #

🌐 Step 1: Get your platform connection string

在你管理的 Supabase 项目仪表板上,点击 Connect 并复制连接字符串(使用会话池或直接连接)。

🌐 On your managed Supabase project dashboard, click Connect and copy the connection string (use the session pooler or direct connection).

步骤 2:备份你的平台数据库 #

🌐 Step 2: Back up your platform database

将角色、架构和数据导出为三个单独的 SQL 文件:

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

1
supabase db dump --db-url "[CONNECTION_STRING]" -f roles.sql --role-only
1
supabase db dump --db-url "[CONNECTION_STRING]" -f schema.sql
1
supabase db dump --db-url "[CONNECTION_STRING]" -f data.sql --use-copy --data-only

这会生成在不同 Postgres 版本之间兼容的 SQL 文件。

🌐 This produces SQL files that are compatible across Postgres versions.

步骤3:准备你自己的自托管实例 #

🌐 Step 3: Prepare your self-hosted instance

在恢复之前,请检查你自托管实例上的以下内容:

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

  • 扩展:启用你的 Supabase 项目使用的任何非默认扩展。你可以通过在托管数据库上查询 select * from pg_extension; 来查看哪些扩展是激活状态的(或者在仪表板中查看数据库扩展)。

步骤4:恢复到你自己的数据库 #

🌐 Step 4: Restore to your self-hosted database

连接到你自己托管的 Postgres 并恢复导出的文件。自托管 Supabase 的默认连接字符串是:

🌐 Connect to your self-hosted Postgres and restore the dump files. The default connection string for self-hosted Supabase is:

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

其中 [POSTGRES_PASSWORD] 是你自托管的 .env 文件中 POSTGRES_PASSWORD 的值。

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

根据你是在 VPS 上自托管 Supabase 还是在本地运行,对于 [your-domain],你可以使用你的域名、服务器 IP 或 localhost。

🌐 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.

运行 psql 来恢复:

🌐 Run psql to restore:

1
psql \
2
--single-transaction \
3
--variable ON_ERROR_STOP=1 \
4
--file roles.sql \
5
--file schema.sql \
6
--command 'SET session_replication_role = replica' \
7
--file data.sql \
8
--dbname "postgres://postgres.your-tenant-id:[POSTGRES_PASSWORD]@[your-domain]:5432/postgres"

session_replication_role 设置为 replica 会在数据导入时禁用触发器,避免列被双重加密等问题。

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

步骤5:核实恢复情况 #

🌐 Step 5: Verify the restore

连接到你自建的数据库并进行一些检查:

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

1
psql "postgres://postgres.your-tenant-id:[POSTGRES_PASSWORD]@[your-domain]:5432/postgres"
1
-- Check your tables are present
2
\dt public.*
3
4
-- Verify row counts on key tables
5
SELECT count(*) FROM auth.users;
6
7
-- Check extensions
8
SELECT * FROM pg_extension;

恢复中包括什么,不包括什么 #

🌐 What's included in the restore and what's not

数据库导出包括你的模式、数据、角色、RLS 策略、数据库函数、触发器和 auth.users。不过,有几件事情需要在你自建的实例上单独配置:

🌐 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:

需要手动设置如何配置
JWT 密钥和 API 密钥生成新的并更新 .env
认证提供商设置(OAuth、Apple 等).env 中配置 GOTRUE_EXTERNAL_* 变量
Edge 函数手动复制到你自托管的实例
存储对象单独传输(本指南不涉及)
SMTP / 邮件设置.env 中配置 SMTP_* 变量
自定义域名和 DNS将你的 DNS 指向自托管服务器

身份验证注意事项 #

🌐 Auth considerations

你的 auth.users 表和相关数据已经包含在数据库导出中,所以用户账户得以保留。不过:

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

  • JWT 密钥不同,你的平台和自托管实例之间不一样。平台项目发的现有令牌将无效。用户需要重新登录。
  • 社交认证提供商(Apple、Google、GitHub 等)需要在你自托管的 .env 文件中进行配置。设置相关的 GOTRUE_EXTERNAL_* 变量。查看 Auth 仓库的 README 了解所有可用选项。
  • 你在 OAuth 提供商控制台(Apple Developer、Google Cloud Console 等)中的 重定向 URL 必须更新为指向你自托管的主机名,而不是 *.supabase.co

Postgres 版本兼容性 #

🌐 Postgres version compatibility

托管的 Supabase 可能运行的 Postgres 版本比自托管的 Docker 镜像更新(托管版是 Postgres 17,而自托管默认是 Postgres 15)。supabase db dump 命令会生成可在主要 Postgres 版本上使用的普通 SQL 文件。

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

记住:

🌐 Keep in mind:

  • 数据导出可能包含仅适用于 Postgres 17 的设置,或者引用在自托管环境中尚不存在的新版本认证和存储中的表/列。请参阅故障排除部分的版本不匹配
  • 先在测试的自托管实例上运行恢复,以找出任何不兼容的地方。
  • 确认你使用的所有扩展在自托管的 Postgres 版本上都可用。

故障排除 #

🌐 Troubleshooting

平台和自托管版本不匹配 #

🌐 Version mismatches between platform and self-hosted

这个平台可能运行比自托管更新的 Postgres 版本(17 对比 15)和更新的认证服务版本。数据导出可能包含在你新的自托管实例中不存在的设置、表或列。

🌐 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.

data.sql 中的常见问题:

  • SET transaction_timeout = 0 - 一个只适用于 Postgres 17 的设置,在 Postgres 15 上会失败
  • COPY 对于自建环境中不存在的表的语句(例如,auth.oauth_clientsstorage.buckets_vectorsstorage.vector_indexes
  • COPY 语句在较新的 Auth 版本中增加了列(例如,auth.flow_state 带有 oauth_client_state_idlinking_target_id

**解决方法:**在恢复之前编辑 data.sql

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

对于缺少的表或列不匹配,先注释掉相关的 COPY ... FROM stdin; 行及其对应的 \. 结束符。先在没有 --single-transaction 的情况下运行恢复,以找出所有错误,然后修复它们,再用 --single-transaction 进行最终恢复。

🌐 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 will minimize these gaps.

扩展不可用 #

🌐 Extension not available

如果恢复失败是因为某个扩展不可用,请检查它是否在你的自托管 Postgres 版本上受支持。你可以使用以下命令列出可用的扩展:

🌐 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:

1
select * from pg_available_extensions;

连接被拒绝 #

🌐 Connection refused

确保你的自托管 Postgres 端口可以访问。在默认的自托管 Supabase 设置中,用户是 postgres.your-tenant-id,Supavisor 端口是 5432

🌐 Make sure your self-hosted Postgres port is accessible. In the default self-hosted Supabase setup, the user is postgres.your-tenant-id with Supavisor on port 5432.

旧版工作室配置 #

🌐 Legacy Studio configuration

在自托管的 Supabase 中,Studio 历史上使用 supabase_admin 角色(超级用户)而不是 postgres。通过 Studio 用户界面创建的对象归 supabase_admin 所有。检查你的 docker-compose.yml 配置 看看 POSTGRES_USER_READ_WRITE 是否设置为 postgres

🌐 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 to see if POSTGRES_USER_READ_WRITE is set to postgres.

自定义角色缺少密码 #

🌐 Custom roles missing passwords

如果你在平台项目中为自定义数据库角色设置了 LOGIN 属性,它们的密码不会包含在转储中。恢复后需要手动设置它们:

🌐 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:

1
ALTER ROLE your_custom_role WITH PASSWORD 'new-password';

额外资源 #

🌐 Additional resources