Supabase 日常运维手册

Supabase 自托管栈日常运维手册:建立六项一键巡检闭环(端口探活、Studio 可用性、认证/存储健康、数据库可查、磁盘水位、日志异常),pg_dump/pg_restore 备份恢复实测与数据目录冷备要点,黑盒探测与告警阈值建议,连接池扩容缩容、升级回滚策略,以及 8 类常见故障的排查手册(全部附实测原始报错,如 ENOIDENTIFIER、PGRST205、invalid_credentials)。

Supabase2026/10/19

Supabase 日常运维手册

目标:为已部署的 Supabase 自托管栈建立「日常巡检 → 备份恢复 → 监控告警 → 扩容缩容 → 升级回滚 → 故障排查」的完整运维闭环。全部巡检项、备份命令与故障报错在实测环境真实执行、回显逐字照抄;部署过程见《Supabase Docker Compose 部署指南》,配置项讲解见《Supabase v1.26.08 配置参数详解》,组件背景见《Supabase v1.26.08 介绍与选型指南》。

一、环境信息

  • 操作系统:Ubuntu 22.04(x86_64);部署形态:官方自托管编排部署(11 个服务全部 healthy)
  • 部署版本:Supabase v1.26.08(2026-08-07 发布;组件版本清单见《Supabase v1.26.08 介绍与选型指南》二、2.2 节)
  • 部署目录:/opt/data/quzuo/supabase-v1.26.08/docker(配置与数据所在,巡检/备份均在此目录执行)
  • 服务入口(实测监听):Studio :8100、API 网关 :8101(HTTP)/:8443(HTTPS)、池化数据库 :5433(会话)/:6543(事务)
  • 关键路径:数据库数据目录 volumes/db/data(实测 67MB)、存储文件目录 volumes/storage、网关路由 volumes/api/kong.yml、池化租户配置 volumes/pooler/pooler.exs
  • 演示凭据:控制台 admin / q1w2e3r4;数据库口令 q1w2e3r4;数据库连接用户名 postgres.your-tenant-id(带租户标识,实测见七、7.4 节)
  • 本机磁盘基线(实测 df -h /):/dev/sda3 786G,已用 262G(35%),可用 490G
  • 服务器地址:192.168.146.128
  • 巡检所需客户端:curl、psql(apt install postgresql-client)、ss、df/du

二、日常巡检

巡检闭环共六项:端口探活 → Studio 可用性 → 认证/存储健康 → 数据库可查 → 磁盘水位 → 日志异常。前五项已固化为一段一键巡检脚本(保存为 check.sh 放在部署目录,实测通过):

#!/bin/bash
# Supabase 日常巡检脚本(部署目录下执行)
cd /opt/data/quzuo/supabase-v1.26.08/docker
ANON=$(grep '^ANON_KEY=' .env | cut -d= -f2)
echo "=== Supabase 日常巡检 $(date '+%F %T') ==="
echo "[1] 端口探活(期望 10 项,5 端口 × IPv4/IPv6 双栈): $(ss -ltn | grep -cE ':(8100|8101|8443|5433|6543)\s')"
echo "[2] Studio:        $(curl -s -o /dev/null -w '%{http_code}' -L http://127.0.0.1:8100/project/default)"
echo "[3] Auth 健康:     $(curl -s -o /dev/null -w '%{http_code}' "http://127.0.0.1:8101/auth/v1/health" -H "apikey: $ANON")"
echo "[4] Storage 健康:  $(curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1:8101/storage/v1/status)"
echo "[5] 数据库可查:    $(PGPASSWORD=q1w2e3r4 psql -h 127.0.0.1 -p 5433 -U postgres.your-tenant-id -d postgres -tAc "select 1" 2>/dev/null)"
echo "[6] 数据目录占用:  $(du -sh volumes/db/data | cut -f1)  根分区: $(df -h / | awk 'NR==2{print $4" 可用 ("$5" 已用)"}')"

实测运行回显(2026-10-19):

=== Supabase 日常巡检 2026-10-19 13:25:20 ===
[1] 端口探活(期望 10 项,5 端口 × IPv4/IPv6 双栈): 10
[2] Studio:        200
[3] Auth 健康:     200
[4] Storage 健康:  200
[5] 数据库可查:    1
[6] 数据目录占用:  67M  根分区: 490G 可用 (35% 已用)

判定标准与解读:[1]=10(少于 10 说明有端口未监听);[2]/[3]/[4]=200;[5]=1(空输出即数据库不可查);[6] 与上次巡检对比增长速率(本文实测基线 67MB)。建议每日一次,全部达标输出 OK 摘要,可接入告警渠道推送(见四、监控告警)。

各项细节:

  • [1] 端口探活:ss -ltn | grep -E ':(8100|8101|8443|5433|6543)\s',实测完整清单见《Supabase Docker Compose 部署指南》4.6 节(2);某项缺失时按七、7.7 节定位具体服务。
  • [2] Studio 可用性:根路径 307 跳转 /project/default 属正常行为(实测 root=307 redirect=http://127.0.0.1:8100/project/default,project=200),判定以跟随重定向后的 200 为准;经网关 8101 访问控制台另有 basic-auth(admin/q1w2e3r4,实测见《Supabase Docker Compose 部署指南》十一、11.5 节)。
  • [3] 认证健康:GET /auth/v1/health 带 anon key 返回 200 与版本 JSON:
{"version":"v2.189.0","name":"GoTrue","description":"GoTrue is a user registration and authentication API"}

⚠️ 反面教材:网关的 /kong/status 端点无论是否携带 anon key 均返回 401(实测),不可作探活端点。

  • [4] 存储健康:GET /storage/v1/status 免鉴权 200。REST 服务的健康判定用数据面验证:带 anon key 查询任一可读表返回 200(实测见七、7.5 节报错对照)。
  • [5] 数据库可查:经池化会话端口执行 select 1,用户名必须带租户标识(postgres.your-tenant-id),实测成功回显:
 session-ok|postgres|postgres
  • [6] 磁盘水位:数据库数据目录(volumes/db/data,实测 67MB)与根分区(实测已用 35%)双指标;阈值建议见四、监控告警。
  • [7] 日志异常:日志查看命令见《Supabase Docker Compose 部署指南》十、常用运维命令。两类实测日志形态供比对——认证服务为 JSON 行格式(异常登录样例,实测逐字):
INFO2, type=login, msg=Bad JWT, msg-no=51, error=jwt claims, remote_ip="10.89.29.1", level=, method=POST, path=/token, request_id=f0fa1cd6ebd6e885cb8586eaa30201d8, data={"grant_type":"password"}

网关为标准访问日志(样例,实测逐字,末两列为响应字节数与状态码):

10.89.29.1 - - [19/Oct/2026:05:04:39 +0000] "POST /auth/v1/token?grant_type=password HTTP/1.1" 400 81 "-" "curl/7.81.0"

异常判定:集中关注 ERROR 级别、5 分钟内大量 invalid_credentials(爆破征兆)、502/504 状态码(后端组件故障)、数据库日志中的 FATAL。

三、备份与恢复

备份策略分四层:数据库逻辑备份(每日)、数据目录冷备(大版本/变更前)、配置文件备份(每次变更后)、存储文件备份(每周)。备份落盘统一放 /opt/data/quzuo/backup/(mkdir -p 创建,实测已存在)。

3.1 数据库逻辑备份(pg_dump,实测通过)

备份从宿主侧经池化端口执行(用户名带租户标识),命令与连接串形态:

mkdir -p /opt/data/quzuo/backup
pg_dump "postgresql://postgres.your-tenant-id:q1w2e3r4@127.0.0.1:5433/postgres" -Fc -f /opt/data/quzuo/backup/supabase-postgres-pooler-$(date +%Y%m%d).dump

实测回显(exit=$?):

exit=0

生成文件(实测):

-rw-r--r-- 1 root root 308K 10月 19 13:28 /opt/data/quzuo/backup/supabase-postgres-pooler-20261019.dump

备份可校验性——用 pg_restore --list 验证归档完整性(实测节选):

;
; Archive created at 2026-10-19 13:28:33 CST
;     dbname: postgres
;     TOC Entries: 628
;     Compression: gzip
;     Dump Version: 1.16-0
;     Format: CUSTOM
;     Integer: 4 bytes
;     Offset: 8 bytes
;     Encoding: UTF8
;

TOC 条目数(实测 628)可作为每日备份的「完整性指纹」记录:异常骤降说明备份不完整。

3.2 数据库恢复与恢复演练(pg_restore,实测通过)

恢复到目标库的命令形态(先建空库再恢复):

PGPASSWORD=q1w2e3r4 psql -h 127.0.0.1 -p 5433 -U postgres.your-tenant-id -d postgres -c "create database doc_restore_drill;"
pg_restore --clean --if-exists -d "postgresql://postgres.your-tenant-id:q1w2e3r4@127.0.0.1:5433/doc_restore_drill" /opt/data/quzuo/backup/supabase-postgres-pooler-20261019.dump

本机做了真实恢复演练,实测要点(回显逐字):

  • 业务数据恢复成功:演练库中 select count(*) from public.doc_demo; 返回 10(与源库一致);
  • --clean --if-exists 在空库上执行会出现非致命报错(先删后建的对象不存在时跳过),实测样例:
pg_restore: 错误: could not execute query: ERROR:  relation "public.notes" does not exist
命令是: DROP POLICY IF EXISTS "public read notes" ON public.notes;
pg_restore: 错误: could not execute query: ERROR:  schema "storage" does not exist
  • 平台初始化对象(storage 等模式)随平台初始化 SQL 创建,恢复业务数据时应改用选择性恢复:pg_restore -n public -t <表名> ...,避免覆盖平台对象;
  • 演练库清理注意:会话池会保持对演练库的后端连接,直接删库报 ERROR: database "doc_restore_drill" is being accessed by other users(实测);先重启池化服务释放动态池再删库即可(实测成功);
  • 恢复后执行 ANALYZE; 更新统计信息,并复跑二、巡检 [5] 验证。

3.3 数据目录冷备(要点)

PostgreSQL 数据目录(volumes/db/data)热拷贝有损坏风险,冷备要点:

  1. 停写窗口:先停止栈再复制数据目录(停启命令见《Supabase Docker Compose 部署指南》十、常用运维命令);
  2. 复制整个目录:cp -a volumes/db/data /opt/data/quzuo/backup/db-data-$(date +%Y%m%d)/;
  3. 恢复:以冷备目录替换 volumes/db/data 后启动栈(版本必须与备份时的 PostgreSQL 大版本一致);
  4. 频率:不作为每日动作,用于 PostgreSQL 大版本升级/平台版本变更前的一次性快照(配合 3.1 逻辑备份双保险)。

3.4 物理在线备份的已知限制(实测报错)

PostgreSQL 自带的 pg_basebackup 在本栈当前配置下不可直接使用,实测原始报错:

pg_basebackup: error: connection to server on socket "/var/run/postgresql" failed: FATAL:  no pg_hba.conf entry for replication connection from host "[local]", user "supabase_admin"

原因:复制连接未在 pg_hba.conf 中放行(官方发行版默认不开放本地复制通道)。两个解法:① 在 volumes/db/pg_hba.conf 追加本地复制条目(local replication supabase_admin trust)后重启数据库服务;② 日常备份继续用 3.1 的 pg_dump(足够覆盖中等规模库,实测 628 对象 308KB 级别)。

3.5 配置与存储文件备份

  • 配置三件套(每次变更后备份,实测部署初值共 <50KB):.env(全栈密钥与参数)、volumes/api/kong.yml(网关路由)、volumes/pooler/pooler.exs(池化租户):
    tar czf /opt/data/quzuo/backup/supabase-config-$(date +%Y%m%d).tgz .env volumes/api/kong.yml volumes/pooler/pooler.exs
    
  • 存储文件:volumes/storage/ 整目录打包(对象存储后端为 file 模式时业务文件全在此);
  • ⚠️ 两个命名数据卷不随目录打包:db-config(pgsodium 解密密钥)与 deno-cache(函数依赖缓存)。前者与数据库内加密数据强绑定,迁移时必须一并导出,导出命令形态与卷挂载说明见《Supabase Docker Compose 部署指南》五、数据持久化说明。

四、监控告警

4.1 黑盒探测项与阈值建议

基于二、巡检项固化为常驻探测(可用 cron 每分钟执行 check.sh 并对失败项告警):

探测项方法告警阈值(建议)
端口存活ss -ltn 计数<10 持续 2 分钟
StudioGET http://127.0.0.1:8100/project/default非 200 持续 2 分钟
认证服务GET /auth/v1/health + anon key非 200 持续 2 分钟
存储服务GET /storage/v1/status非 200 持续 2 分钟
数据库可查池化端口 select 1(带租户用户名)空/超时持续 1 分钟
磁盘水位df -h / 与 du -sh volumes/db/data已用 >80%,或数据目录单日增长 >2GB
认证失败风暴认证服务日志 invalid_credentials 计数5 分钟 >100 次(爆破征兆)
备份有效性每日 dump 的 pg_restore --list TOC 数条目数较前日骤降 >10%

💡 说明:阈值表为工程经验值,落地时结合业务峰谷校准。外部黑盒探测与告警通道对接方式见《钉钉机器人 webhook 告警接入指南》(站内既有篇目,消息体含「巡检项 + 当前值 + 阈值」三要素即可)。磁盘水位与数据库健康类探测也可接入 Prometheus 生态(node_exporter + postgres_exporter),方案见《Prometheus 3.15.0 介绍与选型指南》篇。

4.2 备份保留策略建议

每日逻辑备份保留 14 天、每周 1 份保留 3 个月;备份目录与数据目录分盘存放(本机当前同盘,条件允许迁移至独立备份盘或远端)。每月做一次恢复演练(3.2 节要点)验证备份可用性——备份不可恢复等于没有备份。

五、扩容缩容

Supabase 栈的容量瓶颈主要在三处,扩缩容动作如下:

  • 数据库连接与并发:上调 .env 的 POOLER_MAX_CLIENT_CONN(实测 100,客户端侧上限)与 POOLER_DEFAULT_POOL_SIZE(实测 20,每池后端连接);短连接高频场景引导应用走事务池化端口 6543(无会话状态占用),管理工具走会话端口 5433。修改后按新变量重建 supavisor 服务。
  • API 返回量:PGRST_DB_MAX_ROWS(实测 1000)控制单请求上限,防大查询拖垮数据库;配合应用侧分页而非盲目上调。修改闭环实测见《Supabase v1.26.08 配置参数详解》三、3.2 节(10 行→5 行→回退)。
  • 磁盘:数据库数据目录(实测基线 67MB)随业务线性增长;扩容优先清理旧备份与未使用资源(运行时清理动作详见《Supabase Docker Compose 部署指南》十、常用运维命令),其次扩盘/加挂载点。存储单文件上限:编排内 FILE_SIZE_LIMIT=52428800(50MB),大文件场景调整编排后重建 storage 服务。

⚠️ 注意:单机形态下不建议盲目上调池化参数——每 1 个后端连接约占 PostgreSQL 5-10MB 内存,上调前先看数据库实际连接数与内存余量(select count(*) from pg_stat_activity;,经池化端口执行)。

六、升级与回滚

  • 平台升级:跟随官方月度 Release 滚动组件集合。标准流程:① 升级前完成 3.1 逻辑备份 + 3.3 数据目录冷备 + 3.5 配置备份;② 下载新版本源码,将新版 docker-compose.yml/.env.example/volumes 模板与本机 .env、本地化端口/子网适配(本机三处适配见《Supabase Docker Compose 部署指南》4.4 节)合并;③ 部署目录自带的官方升级脚本 update.sh(v1.26.08 实查存在,含跨版本数据迁移逻辑)可辅助执行数据库结构升级;④ 升级后复跑二、巡检六项全过再对外恢复流量。
  • 数据库大版本升级:PostgreSQL 跨大版本(如 15→17)必须走官方迁移脚本(utils/upgrade-pg17.sh,实查存在),原地改版本号会导致数据目录不兼容、服务起不来。
  • 回滚:回滚 = 配置三件套恢复(3.5)+ 数据目录冷备还原(3.3)或 pg_restore 逻辑还原(3.2)+ 旧版编排文件重新拉起。变更窗口内保留前一版本全部物证是回滚可行性的前提。
  • 回执核验:升级/回滚后除巡检外,重点核验认证登录(grant_type=password 实测链路见《Supabase v1.26.08 配置参数详解》5.5 节)与数据面(业务表查询 200)。

七、故障排查手册

以下 8 个场景均为实测复现,报错原文逐字照抄。通用排查顺序:先跑二、巡检定位故障层(端口/网关/组件/数据库),再按下表对号入座。

7.1 REST 查询返回 401 Invalid authentication credentials

实测复现(错误 apikey):

curl -s "http://127.0.0.1:8101/rest/v1/doc_demo" -H "apikey: wrong-key-123"

实测回显(HTTP 401):

{"message":"Invalid authentication credentials","request_id":"244735a80a09937c27ee65b30b3f896f"}

排查:apikey 头取值错误(错把 JWT_SECRET 当 apikey、复制截断等)。正确取法:grep '^ANON_KEY=' .env | cut -d= -f2;401 由网关 key-auth 拒绝,说明请求未到达数据库层。

7.2 REST 查询返回 404 PGRST205

实测复现(查询不存在的表):

curl -s "http://127.0.0.1:8101/rest/v1/no_such_table" -H "apikey: $ANON"

实测回显(HTTP 404):

{"code":"PGRST205","details":null,"hint":null,"message":"Could not find the table 'public.no_such_table' in the schema cache"}

排查:① 表名/模式拼错;② 新表未授权(grant select on <表> to anon, authenticated;,实测授权后立即可查);③ PostgREST v14 自动侦测 DDL 重载缓存,极端情况重建 rest 服务。

7.3 认证登录 400 invalid_credentials / 注册 422 user_already_exists

实测复现:错误口令登录——

{"code":400,"error_code":"invalid_credentials","msg":"Invalid login credentials"}

重复注册——

{"code":422,"error_code":"user_already_exists","msg":"User already registered"}

排查:400 为口令错误(确认邮箱已注册、口令正确);422 为邮箱已存在(改用登录)。两者是认证服务正常业务报错,非配置故障;若正常口令也报 400,核对 ENABLE_EMAIL_SIGNUP/DISABLE_SIGNUP 取值(《Supabase v1.26.08 配置参数详解》5.5 节)。

7.4 数据库连接报 FATAL (ENOIDENTIFIER)

实测复现(用户名未带租户标识):

PGPASSWORD=q1w2e3r4 psql -h 127.0.0.1 -p 5433 -U postgres -d postgres -c 'select 1;'

实测回显(原始报错):

psql: 错误: 连接到"127.0.0.1"上的服务器,端口5433失败:FATAL:  (ENOIDENTIFIER) no tenant identifier provided (external_id or sni_hostname required)

排查:5433/6543 是池化端口,用户名必须为 postgres.<POOLER_TENANT_ID>(默认 postgres.your-tenant-id)。带租户后连接成功(实测 session-ok|postgres|postgres)。

7.5 网关层 401/403 的三种含义(对号速查)

实测请求实测结果含义
GET /kong/status(有无 anon key 均试)401 {"message":"Unauthorized",...}非公开探活端点,勿用;探活用 /auth/v1/health
GET /rest/v1/(根) + anon key403设计行为:OpenAPI 根路径仅 admin 组(service_role)可见
GET /(控制台,经 8101)无凭据401控制台 basic-auth 保护,带 admin:q1w2e3r4 返回 307 正常

7.6 物理备份 pg_basebackup 失败

实测原始报错:

pg_basebackup: error: connection to server on socket "/var/run/postgresql" failed: FATAL:  no pg_hba.conf entry for replication connection from host "[local]", user "supabase_admin"

排查:默认配置未放行复制连接。解法与替代方案见三、3.4 节。

7.7 某端口未监听(巡检 [1] 计数不足)

排查:① 先看服务整体状态(命令见《Supabase Docker Compose 部署指南》十、常用运维命令),找非 healthy 的服务;② 查对应服务日志(logs -f <服务名>)定位启动失败原因;③ 常见根因:端口被宿主其他进程占用(改 .env 端口键)、数据库未健康导致依赖服务挂起(先恢复 db)、.env 修改后未按新变量重建(《Supabase Docker Compose 部署指南》十一、11.2 节)。

7.8 Studio 打不开/登录失败

排查:① 直连 8100 返回 307 是正常跳转(实测 root=307 redirect=http://127.0.0.1:8100/project/default,项目页 200);② 经 8101 访问需 basic-auth(admin/q1w2e3r4,实测见 7.5 节速查表);③ 控制台登录后若 API 报错,多为 .env 三个 URL 键与实际访问地址不一致(《Supabase v1.26.08 配置参数详解》5.2 节)。

八、常见问题(FAQ)

Q1:巡检 [6] 磁盘增长异常快,先查什么? 先看数据目录(du -sh volumes/db/data)与备份目录(/opt/data/quzuo/backup)谁在涨:数据目录→查大表(select relname, pg_total_relation_size(relid)/1024/1024 AS mb from pg_stat_user_tables order by 2 desc limit 10;,池化端口执行);备份目录→检查保留策略是否生效(4.2 节)。

Q2:备份文件越来越小正常吗? 单日小幅波动正常(TOC 指纹 628 条为准,见 3.1 节);骤降 >10% 说明平台对象丢失,按 7.2 节核对表清单后重备。

Q3:事务模式 6543 能完全替代会话模式 5433 吗? 不能。事务模式不保留会话状态(SET、预编译语句复用失效),管理工具/长事务走 5433,应用高频短查询走 6543(实测两种模式连接成功回显见二、巡检 [5] 与 7.4 节)。

Q4:如何确认某天服务确实出过故障? 网关访问日志带状态码与时间戳(样例见二、[7]),按时间窗检索 5xx;认证服务 JSON 日志按 level/msg 字段过滤。

Q5:升级前必做的三件事? 3.1 逻辑备份、3.3 数据目录冷备、3.5 配置备份(缺一不可),回执核验见六、升级与回滚。

九、参考链接