Supabase迁移工具

更新时间:
复制 MD 格式

本文介绍如何使用Supabase迁移工具将Supabase Cloud项目数据完整迁移至阿里云RDS Supabase实例。

背景信息

Supabase迁移工具可以将Supabase Cloud项目数据完整迁移至阿里云RDS Supabase,并提供可视化的Web界面和实时迁移日志,覆盖用户认证数据、业务数据、对象存储文件和边缘函数四类核心数据资产。

功能特性

  • Web UI:提供可视化配置、一键迁移、实时进度和日志查看。

  • 支持按需指定 schemas、buckets 和 functions 的迁移范围,无需整库全量迁移。

  • 支持在恢复前清理目标端,避免与已有对象冲突。

  • Storage 迁移自动保留正确的 MIME Content-Type,文件迁移后可直接在线预览。

  • Edge Functions 支持 CLI 和 API 两种部署方式,迁移到 RDS Supabase 时推荐使用 API 方式。

  • 支持通过环境变量(MIGRATOR_ 前缀)覆盖配置项,便于在容器化部署中传入凭据。

  • 版本检查:自动检测 pg_dump 与源端、目标端数据库服务器版本的兼容性,避免因版本不匹配导致迁移失败。

迁移管道

迁移工具支持以下4条迁移管道,按照固定顺序依次执行:

顺序

管道

说明

1

Auth

迁移 auth.usersauth.identities 等用户认证数据,可选包含 auth.mfa_factors

2

Database

使用 pg_dump/pg_restore 迁移数据库 schema 和 data,支持指定 schemas 范围。

3

Storage

通过 Supabase Storage REST API 流式下载源端所有 bucket 中的文件,并上传至目标端,自动保留 MIME Content-Type。

4

Edge Functions

下载源端函数的 eszip 包,通过 API 或 Supabase CLI 部署到目标端。

重要

Auth 管道必须在 Database 管道之前执行。原因是业务表通常包含指向 auth.users 的外键,若先恢复业务表则会因外键约束失败。

Auth 用户数据迁移

仅迁移 auth 表的数据(不含 DDL),因为目标端 GoTrue 服务已自动初始化并管理 auth schema。

  • 默认迁移 auth.usersauth.identities

  • 可选包含 auth.mfa_factors

  • 使用 SET session_replication_role = replica 跳过触发器与约束检查,加快批量插入。

  • 冲突(duplicate key)作为 warning 处理,不中断迁移。

数据库迁移

使用 pg_dump/pg_restore 完整迁移数据库 schema 和 data。

  • 支持 custom(推荐)和 plain 两种 dump 格式。

  • 可指定特定 schemas(例如仅迁移 public),无需整库迁移。

  • 可选在恢复前清理目标端(DROP SCHEMA CASCADE + CREATE),避免与已有对象冲突。

  • 可选包含 roles。

Storage 文件迁移

通过 Supabase Storage REST API 完成 bucket 与文件的复制。

  • 自动创建目标端不存在的 bucket,已存在的 bucket 不修改属性。

  • 流式传输文件内容,支持大文件迁移而不会占满内存。

  • 并发控制:默认 5 个 worker 并行传输。

  • 保留正确的 Content-Type,文件迁移后可直接在线预览。

Edge Functions 部署

支持两种部署方式,迁移到 RDS Supabase 时推荐 API 方式。

  • API 方式(推荐):通过 POST /functions/v1/manage/deploy?slug={slug} 接口以 multipart/form-data 方式上传函数包。

  • CLI 方式:调用 supabase functions deploy 命令完成部署。

前提条件

  • 已创建 RDS Supabase 项目并处于运行中状态。创建方法请参见开通RDS Supabase项目

  • 已将运行迁移工具的机器出口 IP 添加到下列实例的白名单中:

    • RDS Supabase 项目托管的 RDS PostgreSQL 实例白名单,用于 pg_restore 直连。添加方法,请参见设置IP白名单

    • RDS Supabase实例配置白名单,添加方式为在 RDS Supabase 项目详情页的白名单信息区域添加。

    • 源端 Supabase 项目侧也需放通迁移工具的出口 IP。

  • 运行迁移工具的机器已安装 Python 3.10 及以上版本。

  • 运行迁移工具的机器已安装 PostgreSQL 客户端工具(pg_dumppg_restorepsql),且客户端版本不低于源端和目标端 PostgreSQL 服务器版本中的较高者。

注意事项

  • RDS Supabase 默认数据库为supabase_db,目标端连接串中必须使用该数据库名,例如 postgresql://postgres:PASSWORD@pgm-xxx.pg.rds.aliyuncs.com:5432/supabase_db。若误连到 postgres 库,会导致业务表恢复到错误的数据库。

  • 谨慎使用清理目标端选项。配置项 clean_target_before_restore 启用后会在恢复前执行 DROP SCHEMA ... CASCADE,目标端该 schema 下的所有对象和数据将被永久删除且不可恢复。首次迁移到空实例时可开启,已有业务数据时请务必关闭。

  • 迁移管道顺序不可调整。Auth 必须先于 Database 执行,否则业务表对 auth.users 的外键约束会导致 Database 恢复失败。

  • Storage 迁移采用"跳过已存在文件"策略,不会覆盖目标端已有的同名文件,bucket 也只创建不存在的。若需重新迁移,请先在目标端手动删除对应文件或 bucket。

  • Auth 管道仅迁移数据,不迁移 DDL。因为目标端的 GoTrue 服务已自动初始化 auth schema,重复创建会冲突。

  • Edge Functions 通过 API 方式部署时需要目标端 agent-runtime 服务正常运行。RDS Supabase 默认已启用该服务。

步骤一:部署迁移工具

推荐使用 Docker 方式部署,镜像内已包含 Python 3.12 和 PostgreSQL 18 客户端(向下兼容 PG 17/15),无需手动安装依赖。

下载项目源代码

下载迁移工具源代码包supabase-migration-v1.1.zip,并解压到运行迁移工具的机器上。源代码包中包含 Docker Compose 配置文件(docker-compose.yaml)、Dockerfile、配置文件示例(config/default.yaml.example)以及 Python 源代码等,是后续所有部署方式的基础。

方式一:Docker Compose 部署(推荐)

  1. 在运行迁移工具的机器上,准备 supabase-migrator 工具目录并进入。

  2. 从示例文件创建配置文件。

    cp config/default.yaml.example config/default.yaml

    参考步骤二:配置迁移参数编辑 config/default.yaml,填入源端和目标端的连接信息等迁移参数。

  3. 启动迁移工具容器。

    docker compose up -d

    容器启动后,访问 http://<迁移工具机器IP>:8080 即可打开 Web UI。

方式二:Docker run 部署

适用于无 docker-compose 环境的场景。先构建镜像,再根据是否需要将凭据落盘选择启动方式。

  1. 构建镜像。

    docker build -t supabase-migrator .
  2. 根据需要选择以下任一方式启动容器。

    挂载配置文件

    将本地编辑好的 config/default.yaml 挂载到容器中,凭据以文件形式管理。

    docker run --rm -p 8080:8080 \
      -v ./config/default.yaml:/app/config/default.yaml:ro \
      supabase-migrator

    纯环境变量

    通过环境变量代替配置文件,避免在磁盘上存储敏感凭据。环境变量使用 MIGRATOR_ 前缀加双下划线 __ 表示层级,例如:

    docker run --rm -p 8080:8080 \
      -e MIGRATOR_SOURCE__PROJECT_REF="your-project-ref" \
      -e MIGRATOR_SOURCE__DATABASE_URL="postgresql://postgres:PASSWORD@db.xxx.supabase.co:5432/postgres" \
      -e MIGRATOR_SOURCE__SERVICE_ROLE_KEY="eyJ..." \
      -e MIGRATOR_SOURCE__MANAGEMENT_API_TOKEN="sbp_..." \
      -e MIGRATOR_SOURCE__API_BASE="https://xxx.supabase.co" \
      -e MIGRATOR_TARGET__DATABASE_URL="postgresql://postgres:PASSWORD@pgm-xxx.pg.rds.aliyuncs.com:5432/supabase_db" \
      -e MIGRATOR_TARGET__SERVICE_ROLE_KEY="eyJ..." \
      -e MIGRATOR_TARGET__API_BASE="http://your-rds-supabase/" \
      supabase-migrator

方式三:本地源码部署

适用于希望调试或定制工具逻辑的场景,需自行准备 Python 和 PostgreSQL 客户端。

  1. 安装 PostgreSQL 客户端工具(版本 ≥ 17)。以 macOS 为例:

    # 安装 PostgreSQL 17 客户端
    brew install postgresql@17
    
    # 验证版本
    /opt/homebrew/opt/postgresql@17/bin/pg_dump --version
    说明

    无需将客户端工具加入系统 PATH,后续在配置文件中通过 pg_bin_path 指定目录即可。

  2. 在工具目录下创建 Python 虚拟环境并安装依赖。

    cd supabase-migrator
    python3 -m venv .venv
    source .venv/bin/activate
    pip install -r requirements.txt
  3. 从示例文件创建配置文件。

    cp config/default.yaml.example config/default.yaml

    参考步骤二:配置迁移参数编辑 config/default.yaml,填入源端和目标端的连接信息等迁移参数。

  4. 启动服务。

    source .venv/bin/activate
    PYTHONPATH=src python -m uvicorn supabase_migrator.main:app --host 127.0.0.1 --port 8080

    启动成功后,浏览器访问 http://127.0.0.1:8080 打开 Web UI。

步骤二:配置迁移参数

编辑 config/default.yaml,填入源端和目标端的连接信息及各管道的开关。完整示例如下:

source:
  project_ref: "your-project-ref"
  database_url: "postgresql://postgres:YOUR_PASSWORD@db.xxx.supabase.co:5432/postgres"
  service_role_key: "eyJ..."
  management_api_token: "sbp_..."
  api_base: "https://xxx.supabase.co"

target:
  project_url: "http://your-rds-supabase/"
  database_url: "postgresql://postgres:YOUR_PASSWORD@pgm-xxx.pg.rds.aliyuncs.com:5432/supabase_db"
  service_role_key: "eyJ..."
  api_base: "http://your-rds-supabase/"

migration:
  auth:
    enabled: true
  database:
    enabled: true
    pg_bin_path: "/opt/homebrew/opt/postgresql@17/bin"   # 本地部署时填客户端工具目录;Docker 部署可省略
    clean_target_before_restore: false                    # 谨慎开启,会 DROP SCHEMA CASCADE
  storage:
    enabled: true
  edge_functions:
    enabled: true
    deploy_method: "api"                                  # 推荐 api,RDS Supabase 场景下更可靠
说明

如不希望将凭据写入磁盘文件,可通过环境变量覆盖配置项(前缀 MIGRATOR_,双下划线 __ 表示层级):

export MIGRATOR_SOURCE__DATABASE_URL="postgresql://..."
export MIGRATOR_SOURCE__SERVICE_ROLE_KEY="eyJ..."

凭据获取速查表

参数

用途

获取方式

source.project_ref

标识源端项目

Supabase Dashboard URL 中的项目 ID,即 xxx.supabase.co 中的 xxx 部分。

source.database_url

源端数据库连接串(pg_dump 直连)

Supabase Dashboard > Settings > Database > Connection string (URI)。

source.service_role_key

源端 Storage / Auth API 鉴权

Supabase Dashboard > Settings > API > service_role key。

source.management_api_token

Edge Functions 管理

Supabase Dashboard > Account > Access Tokens,以 sbp_ 开头。

source.api_base

源端 REST API 基础地址

格式为 https://<project_ref>.supabase.co

target.project_url

目标端首页地址

在 RDS Supabase 项目详情页 > 网络信息 区域获取外网连接地址

target.database_url

目标端数据库连接串(pg_restore 直连)

格式为 postgresql://postgres:PASSWORD@<pg实例连接地址>:5432/supabase_db。在 RDS Supabase 项目托管的 PG 实例详情页获取连接地址,数据库名固定为 supabase_db

target.service_role_key

目标端 Storage / Auth / Functions API 鉴权

在 RDS Supabase 项目详情页 > API Key 中复制 ServiceKey 的值。详见附录:获取service API key

target.api_base

目标端 API 网关地址

RDS Supabase 内置 Kong 网关地址,通常与 target.project_url 相同。

步骤三:执行迁移

  1. 在浏览器中访问迁移工具的 Web UI 地址(本地部署为 http://127.0.0.1:8080,Docker 部署为 http://<迁移工具机器IP>:8080)。

  2. 配置页面中,确认已填入步骤二的源端、目标端参数,单击测试连接,验证迁移工具是否能正常访问源端和目标端。

    说明

    如测试失败,请检查:迁移工具出口 IP 是否已加入所有相关白名单、连接串中数据库名是否正确(目标端应为 supabase_db)、service_role_key 是否完整复制。

  3. 切换到迁移页面,根据需要选择迁移方式:

    • 开始全量迁移:按 Auth → Database → Storage → Edge Functions 顺序执行所有已启用的管道,适用于完整迁移场景。

    • 仅迁移 XXX:仅执行单个管道,适用于补迁、重试或分阶段迁移场景。

  4. 切换到日志页面,实时查看迁移进度、当前管道执行状态以及错误信息。

    重要

    迁移过程中请勿关闭浏览器窗口或停止迁移工具进程,否则会中断迁移。中断后可重新执行,工具使用临时目录存放中间文件,每次执行后自动清理,不会污染下一次执行。

验证迁移结果

迁移完成后,建议从以下几个维度逐一验证目标端 RDS Supabase 的数据完整性:

  • 验证 Auth 数据:登录 RDS Supabase Dashboard,进入 Authentication > Users,对比用户总数是否与源端一致。

  • 验证业务数据:连接目标端 supabase_db,分别在源端和目标端执行以下 SQL 对比业务表数量和关键表的行数。

    -- 表总数
    SELECT count(*) FROM information_schema.tables WHERE table_schema = 'public';
    
    -- 关键表行数(替换为您的实际表名)
    SELECT count(*) FROM public.your_table;
  • 验证 Storage 文件:在 RDS Supabase Dashboard 进入 Storage,确认 bucket 列表完整,并随机抽查若干 bucket 下的文件能正常预览或下载。

  • 验证 Edge Functions:进入 Edge Functions 列表,确认函数已成功部署,通过 curl 或 Dashboard 内的测试按钮调用函数验证返回结果是否正常。

常见问题

  • Q:迁移失败后可以重试吗?
    A:可以。每次迁移使用独立的临时目录(结束后自动清理),不会影响下一次执行。直接在 Web UI 重新点击开始全量迁移即可。

  • Q:Storage 迁移时目标端已有相同文件怎么处理?
    A:已存在的文件会被跳过(不覆盖),bucket 也会跳过已存在的。

  • Q:Database 迁移报错 pg_dump version mismatch 怎么办?
    A:pg_dump 客户端版本必须不低于源端和目标端中的更高版本。在配置中将 pg_bin_path 指向更高版本的 PostgreSQL 客户端工具目录即可。

  • Q:Edge Functions 部署失败怎么办?
    A:使用 API 方式部署时,确认目标端的 edge-runtime(agent-runtime)服务正常运行,并且配置项 target.api_base 设置正确。

  • Q:可以只迁移其中一个管道吗?
    A:可以。在 Web UI 的迁移页面点击对应的仅迁移 XXX按钮,或通过 API 调用 /api/migrate/auth/api/migrate/database 等单独端点。

  • Q:Docker 容器中如何查看日志?
    A:两种方式:

    • 在 Web UI 的日志页面实时查看。

    • 在迁移工具机器上执行 docker logs -f migrator 查看容器标准输出。