Supabase on k3s 生产级多项目平台完整实战指南

基于 k3s + Helm 3 + cert-manager + Traefik 构建的企业级多租户 Supabase 平台。
实现 “一条命令开通一套独立 Supabase”(独立 Kubernetes Namespace、独立 Postgres 17 数据库、独立连接池、现代 sb_ 密钥与非对称 JWKS、独立子域名与自动续期 TLS 证书)。


目录


一、平台架构与核心特性

                       Internet (业务用户 / AI 客户端)
                                     │
                 ┌───────────────────┴───────────────────┐
                 │                                       │
     HTTPS 业务流量 (api-a.example.com)          本地安全隧道 (make mcp)
                 │                                       │
                 ▼                                       ▼
    ┌───────────────────────────┐           ┌───────────────────────────┐
    │  Traefik Ingress (k3s)    │           │ kubectl 原生加密转发通道   │
    │  cert-manager (Let's Encry│           │ (零公网暴露面,直连 Studio)│
    └────────────┬──────────────┘           └────────────┬──────────────┘
                 │ (Kong 网关入口: 自动映射 sb_ 密钥)    │
                 ▼                                       │
┌────────────────────────────────────────────────────────┼───────────────┐
│ Namespace: proj-a                                      │               │
│                                                        ▼               │
│   ┌────────────────────────────────────────────────────────┐           │
│   │ Kong API Gateway 3.9 (内置 Lua 转换层)                  │           │
│   │ - 接收 sb_publishable_ ➔ 映射为 ANON_KEY_ASYMMETRIC     │           │
│   │ - 接收 sb_secret_      ➔ 映射为 SERVICE_ROLE_ASYMMETRIC │           │
│   │ - 兼容传统 HS256 ANON_KEY / SERVICE_ROLE_KEY          │           │
│   └───────┬───────────────────────────────┬────────────────┘           │
│           │                               │                            │
│           ▼                               ▼                            │
│   ┌────────────────┐             ┌────────────────────────────────┐    │
│   │ Auth (GoTrue)  │             │ Studio Pod (Web 后台 + MCP)     │    │
│   │ - ES256 签发   │             │ - UI 访问: 端口 3000 (Kong)     │    │
│   │ - JWT_KEYS     │             │ - MCP 协议: /api/mcp (本地隧道) │    │
│   └───────┬────────┘             └────────────────────────────────┘    │
│           │                                                            │
│           ▼                                                            │
│   ┌────────────────────────────────────────────────────────┐           │
│   │ 独立连接池: supabase-proj-a-pooler (PgBouncer)         │           │
│   │ - 端口 6543: Transaction 事务池 (Serverless / API)     │           │
│   │ - 端口 5432: Session 会话池 (后端常驻长连接)           │           │
│   └───────┬────────────────────────────────────────────────┘           │
│           │ (受 NetworkPolicy 零信任防火墙保护,阻断外部 Namespace)     │
│           ▼                                                            │
│   ┌────────────────────────────────┐                                   │
│   │ Postgres 17 Pod (PVC 本地存储) │                                   │
│   └────────────────────────────────┘                                   │
└────────────────────────────────────────────────────────────────────────┘

核心特性亮点

  1. 双轨密钥体系:原生支持官方最新 sb_publishable_... / sb_secret_... 密钥以及 EC P-256 (ES256) 非对称 JWKS,同时 100% 兼容传统 HS256 长 JWT。
  2. 多租户强隔离:每项目独立 Kubernetes Namespace、独立数据存储、独立子域名与独立 TLS 证书。
  3. 内置连接池:自带独立的 Pooler(6543 事务池 / 5432 会话池),杜绝数据库高并发连接耗尽。
  4. AI Agent (MCP) 原生打通:为 Cursor、Claude Code、Codex 提供零公网暴露的原生安全隧道,自动派发客户端配置。
  5. 完整生产加固:默认开启 NetworkPolicy 数据库防火墙、剥离超管特权、集成即时与定时备份 CronJob。

二、前置环境准备

1. 基础依赖

  • 操作系统:Ubuntu 20.04/22.04/24.04 或 Debian 11/12
  • 软件环境
    • k3s 正常运行,kubectl 拥有集群读写权限
    • helm 3.x 已安装并在 PATH 中
    • cert-manager 运行正常(cert-manager 命名空间下 3 个 Pod 均处于 Running 状态)
    • 本地常用命令:bashnode (>=16)、python3opensslgzipcurljq

2. 域名 DNS 解析(强烈建议泛域名解析)

在你的 DNS 提供商后台添加一条泛域名 A 记录指向 VPS 公网 IP:

*.supabase.yourdomain.com  ->  <你的 VPS 公网 IP>

配置完成后,后续开通任意项目(如 app1.supabase.yourdomain.com)均无需重复配置 DNS。


三、集群初始配置(一次性)

1. 配置全局参数

复制模板并编辑全局 .env

cp .env.example .env

修改关键配置:

# 用于 Let's Encrypt 证书过期告警通知的真实邮箱
ACME_EMAIL=admin@yourdomain.com

# Ingress 类型(k3s 默认是 traefik)
INGRESS_CLASS=traefik

# 存储卷类型(k3s 默认是 local-path)
STORAGE_CLASS=local-path

# cert-manager 的 ClusterIssuer 名称
ISSUER=letsencrypt-prod

# 若集群中尚无该 ClusterIssuer,设为 true 可由 bootstrap 自动创建
BOOTSTRAP_ISSUER=true

2. 执行集群体检与证书签发器初始化

make bootstrap

检查 cert-manager 状态;若 ClusterIssuer 不存在,会自动创建基于 HTTP-01 验证的 Let's Encrypt 生产证书签发器。

3. 同步上游 Helm Chart

make charts

拉取上游 supabase-kubernetes 基础编排模板至本地 charts/ 目录。


四、项目创建与上线流程

步骤 1:脚手架化一个新项目

make new PROJECT=proj-a HOST=proj-a.supabase.yourdomain.com

该命令会自动执行全套工程初始化:

  1. 密码学引擎生成全套凭据
    • 自动生成现代 sb_publishable_...sb_secret_... 密钥。
    • 生成 EC P-256 密钥对,构造公钥 JWT_JWKS 与私钥 JWT_KEYS,签发 ES256 格式非对称 Token。
    • 兼容生成传统 HS256 JWT、数据库超管密码、MinIO 访问密钥等。
  2. 生成项目文件清单
    • projects/proj-a/.secrets:完整凭据明细(已锁定 600 权限,Git 忽略)。
    • projects/proj-a/values.yaml:已预设连接池限制、NetworkPolicy 与现代认证配置。
    • projects/proj-a/pooler.yaml:独立连接池(PgBouncer)K8s 编排清单。
    • projects/proj-a/mcp.json:AI Agent(Cursor / Claude)一键连接配置。
    • projects/proj-a/example-hooks.sql:Auth Hook 示例脚本。

步骤 2:一键部署到集群

make deploy PROJECT=proj-a

部署处理流程:

  • 自动创建 proj-a 命名空间。
  • 部署 Postgres 17、Kong、Auth、PostgREST、Storage、Studio、Realtime 全套微服务。
  • 自动拉起独立连接池服务 supabase-proj-a-pooler
  • cert-manager 自动向 Let's Encrypt 申请签发 TLS 证书。

步骤 3:访问 Supabase Studio 后台

  • 访问地址https://proj-a.supabase.yourdomain.com
  • 登录凭证:查看 projects/proj-a/.secrets 中的 DASHBOARD_USERNAMEDASHBOARD_PASSWORD

五、现代应用客户端接入(SDK 规范)

部署完成后,查看生成的凭据:

make secrets PROJECT=proj-a

1. 前端应用接入(Next.js / Vite / React / Vue / Flutter / 移动端)

本项目同时支持官方最新的 sb_publishable_ 密钥与传统 ANON_KEY

# 环境变量推荐(支持最新官方格式):
NEXT_PUBLIC_SUPABASE_URL=https://proj-a.supabase.yourdomain.com
NEXT_PUBLIC_SUPABASE_ANON_KEY=<填写 .secrets 中的 SUPABASE_PUBLISHABLE_KEY 或 ANON_KEY>
import { createClient } from '@supabase/supabase-js'

export const supabase = createClient(
  process.env.NEXT_PUBLIC_SUPABASE_URL!,
  process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
)

安全底线:前端浏览器代码只能使用 Publishable / Anon Key,严禁暴露 Secret Key。所有暴露给客户端的表必须在后台开启 Row Level Security (RLS)

2. 后端服务端接入(Node.js / Python / Go / Server Action)

后端需要绕过 RLS 执行管理员权限操作时:

SUPABASE_URL=https://proj-a.supabase.yourdomain.com
SUPABASE_SERVICE_ROLE_KEY=<填写 .secrets 中的 SUPABASE_SECRET_KEY 或 SERVICE_ROLE_KEY>
import { createClient } from '@supabase/supabase-js'

export const supabaseAdmin = createClient(
  process.env.SUPABASE_URL!,
  process.env.SUPABASE_SERVICE_ROLE_KEY!,
  { auth: { autoRefreshToken: false, persistSession: false } }
)

3. 后端服务直连数据库(连接池推荐)

在集群内部或通过隧道连接 Postgres 时,建议优先连接事务连接池(6543 端口)

# 事务连接池 (Transaction Pooler,推荐 Serverless / API 函数并发调用):
postgresql://postgres:<密码>@supabase-proj-a-pooler.proj-a.svc.cluster.local:6543/postgres

# 会话连接池 (Session Pooler,供传统常驻后端服务):
postgresql://postgres:<密码>@supabase-proj-a-pooler.proj-a.svc.cluster.local:5432/postgres

# 裸库直连 (仅供执行 DDL 迁移或批量结构同步):
postgresql://postgres:<密码>@supabase-proj-a-supabase-db.proj-a.svc.cluster.local:5432/postgres

六、AI Agent (MCP) 架构与配置

本项目为 Studio 内置的 Model Context Protocol (MCP) 端点(/api/mcp)封装了原生安全隧道。

1. 启动本地安全端口转发

# 启动本地代理通道(支持多项目多端口,默认 8080)
make mcp PROJECT=proj-a PORT=8080

2. 客户端配置(复制即用)

直接打开项目目录下自动生成的 projects/proj-a/mcp.json,或执行 make mcp-config PROJECT=proj-a

  • Cursor (.cursor/mcp.json)

    {
      "mcpServers": {
        "supabase-proj-a": {
          "url": "http://127.0.0.1:8080/api/mcp"
        }
      }
    }
    
  • Claude Desktop / Claude Code (claude_desktop_config.json)
    将上述配置块添加至 mcpServers 对象中。

  • Codex CLI
    直接使用 http://127.0.0.1:8080/api/mcp 作为该项目的 MCP 服务端点。

3. 验证 MCP 连通性

新开终端执行握手健康测试:

make mcp-check PORT=8080

返回标准 JSON-RPC 2.0 握手数据即表明通道正常。


七、生产级加固与安全运维

1. 独立连接池架构 (Pooler 6543/5432)

  • 运作机制make deploy 自动在 Namespace 内拉起 supabase-<project>-pooler
  • 并发调优:PostgREST 内部连接池已设为 20,Auth 设为 20。高并发流量将由 PgBouncer 的 6543 事务池复用底层连接,防止 Postgres 进程崩溃。

2. 最小权限安全加固 (Remove Superuser)

对齐官方最新权限安全加固标准:

make secure-roles PROJECT=proj-a

执行动作:

  • public 架构属主从 supabase_admin 收敛给常规 postgres 账号。
  • authenticatorsupabase_auth_adminsupabase_storage_admin 派生独立的高强度隔离密码,并自动回写至 .secrets

3. 零信任网络隔离 (NetworkPolicy)

  • 默认生效networkPolicy.db.enabled: true 已在模板默认开启。
  • 安全效果:在 Kubernetes CNI 网络层直接拦截非本项目 Pod 对 5432 端口的访问,杜绝跨 Namespace 的未授权探测。

4. 现代 Auth 扩展 (Auth Hooks / Passkeys / SAML)

projects/<project>/values.yaml 中,可通过取消注释直接启用企业级认证功能:

  • Auth Hooks (事件拦截与 Claims 注入)
    projects/<project>/example-hooks.sql 导入数据库后,在 values.yaml 开启:
    - name: GOTRUE_HOOK_CUSTOM_ACCESS_TOKEN_ENABLED
      value: "true"
    - name: GOTRUE_HOOK_CUSTOM_ACCESS_TOKEN_URI
      value: "pg-functions://postgres/public/custom_access_token_hook"
    
  • Passkeys (WebAuthn 生物识别登录)
    - name: GOTRUE_PASSKEY_ENABLED
      value: "true"
    - name: GOTRUE_WEBAUTHN_RP_ID
      value: "proj-a.supabase.yourdomain.com"
    - name: GOTRUE_WEBAUTHN_RP_ORIGINS
      value: "https://proj-a.supabase.yourdomain.com"
    
  • SAML 2.0 SSO (企业单点登录)
    - name: GOTRUE_SAML_ENABLED
      value: "true"
    - name: GOTRUE_SAML_EXTERNAL_URL
      value: "https://proj-a.supabase.yourdomain.com"
    

5. 官方云端数据平滑迁移 (import-cloud)

若需要将 Supabase Cloud 官方托管项目的数据库迁移到自建平台:

make import-cloud PROJECT=proj-a FILE=path/to/cloud_dump.sql

自动执行 SQL 导入,并自动执行属主自愈,修复表权限以适配自建 Studio。

6. Postgres 17 平滑升级套件 (upgrade-pg17)

make upgrade-pg17 PROJECT=proj-a

自动探测版本。新项目默认即为 PG 17;针对已有旧版本项目,命令会强制触发升级前全量快照备份,并给出原地平滑升级方案。

7. 灾备备份与恢复系统 (Backup / Cron / Restore)

# 1. 随时执行即时逻辑全备 (自动 gzip 压缩并校验完整性,落盘于 backups/<project>/)
make backup PROJECT=proj-a

# 2. 为项目下发每日自动备份 CronJob (默认每日凌晨 2 点执行)
make cron-backup PROJECT=proj-a CRON="0 2 * * *"

# 3. 灾难数据受控恢复 (带交互式确认防止误操作)
make restore PROJECT=proj-a FILE=backups/proj-a/supabase-proj-a-xxx.sql.gz

8. 生产 6 维健康与安全体检 (make audit)

随时一键审查运行中项目的健康状态:

make audit PROJECT=proj-a

体检涵盖维度:

  1. 工作负载健康度:检查所有 Pod 是否处于 RunningReady 状态。
  2. 崩溃重启风暴:预警频繁重启或 OOMKilled 的容器。
  3. TLS 证书生效审计:检查 cert-manager Certificate 是否达到 Ready=True
  4. NetworkPolicy 防火墙:验证 5432 端口策略隔离是否生效。
  5. Postgres 实时连接与体积:读取物理体积、当前活动连接数与连接上限。
  6. 本地凭据权限合规:检测 .secrets 权限是否严格为安全级别 600

八、全套命令速查表

操作领域命令说明
基础底座make bootstrap体检 cert-manager 与 ClusterIssuer
make charts同步上游 Helm 编排模板
租户管理make new PROJECT=xxx HOST=xxx自动生成全套密钥、mcp.json 与加固版 values.yaml
make deploy PROJECT=xxx部署或更新指定租户微服务与连接池
make upgrade PROJECT=xxx修改 values.yaml 后重新应用配置
make list列出集群中所有已部署的项目及状态
make status PROJECT=xxx查看指定项目的 Pod / Ingress / PVC 资源
make destroy PROJECT=xxx卸载项目应用(加 PURGE=1 连数据卷一起销毁)
排错与运维make logs PROJECT=xxx C=auth查看微服务日志(支持 auth/rest/db/studio/storage/kong
make shell-db PROJECT=xxx一键以管理员身份进入 Postgres 的 psql 交互终端
make secrets PROJECT=xxx查看当前项目的完整密钥清单(包含直连/连接池串)
make audit PROJECT=xxx执行项目生产安全与 6 维健康审计体检
make secure-roles PROJECT=xxx一键执行最小权限收敛与微服务子密码隔离
数据与迁移make backup PROJECT=xxx执行数据库即时导出全量备份
make cron-backup PROJECT=xxx为项目部署每日自动备份 CronJob
make restore PROJECT=xxx FILE=...从备份文件受控恢复数据库
make import-cloud PROJECT=xxx FILE=...从 Supabase Cloud 导出文件一键迁移导入
make upgrade-pg17 PROJECT=xxx检查并指导数据库平滑升级至 Postgres 17
AI 协同make mcp PROJECT=xxx [PORT=8080]启动本地加密 MCP 端口转发安全隧道
make mcp-check [PORT=8080]测试本地 MCP 隧道 JSON-RPC 握手连通性
make mcp-config PROJECT=xxx输出 Cursor / Claude Code / Codex 客户端配置片段