AgentDock
模板web-nextjs

数据层:Supabase

在 web-nextjs 中使用 Supabase,包括自部署(Docker Compose)完整配置指南。

数据层:Supabase

Supabase Cloud vs 自部署

特性Supabase Cloud自部署(Docker Compose)
上手速度⚡ 快速,几分钟即可创建项目需要 Docker 知识和服务器配置
免费额度有(2 个项目,500MB 数据库)无限制(取决于你的硬件)
数据掌控数据存储在 Supabase 云端数据完全在你自己的服务器上
存储限制有(免费版 1GB)无限制(取决于硬盘容量)
扩展性自动扩展,按需升级需要手动扩展
维护成本零(Supabase 团队维护)需要自行维护、升级、备份
国内访问较慢(服务器在海外)快(部署在国内服务器)

建议:开发阶段使用 Supabase Cloud 快速开始;生产环境推荐自部署,以获得更好的数据掌控和国内访问速度。

快速开始:Docker Compose 自部署

前置条件

  • Docker ≥ 20.10
  • Docker Compose ≥ 2.0
  • 服务器开放端口:8000(Supabase Studio)、54321(API Gateway)、5432(PostgreSQL)

步骤 1:克隆官方 docker-compose 配置

git clone --depth 1 https://github.com/supabase/supabase
cd supabase/docker
cp .env.example .env

步骤 2:关键环境变量说明

编辑 .env 文件,以下变量必须修改

# 数据库密码(必改,默认值不安全)
POSTGRES_PASSWORD=your-super-strong-password

# JWT 密钥(至少 32 位随机字符串)
# 生成方式:
openssl rand -base64 32
JWT_SECRET=your-generated-jwt-secret

# API 密钥(ANON_KEY 公开使用,SERVICE_ROLE_KEY 仅服务端使用)
# 使用官方生成器:https://supabase.com/docs/guides/self-hosting/docker#generate-api-keys
ANON_KEY=eyJh...
SERVICE_ROLE_KEY=eyJh...

# Studio 登录凭据
DASHBOARD_USERNAME=admin
DASHBOARD_PASSWORD=your-strong-dashboard-password

步骤 3:启动所有服务

docker compose up -d

服务包括:PostgreSQL、Kong API Gateway、Supabase Studio、Auth、Realtime、Storage、Edge Functions 等。

步骤 4:验证

访问 http://localhost:8000(Supabase Studio),使用 .env 中的 DASHBOARD_USERNAME / DASHBOARD_PASSWORD 登录。

参考:Supabase Self-Hosting Docker Guide

身份认证配置

邮件发送配置(SMTP)

开发环境默认使用 Inbucket(邮件都路由到 http://localhost:54324,方便调试)。生产环境需配置真实 SMTP。

.env 中 SMTP 配置:

SMTP_HOST=smtp.example.com
SMTP_PORT=587
SMTP_USER=your-smtp-user
SMTP_PASS=your-smtp-password
SMTP_SENDER_NAME=My App

推荐的国内邮件服务

  • 阿里云邮件推送(DirectMail)
  • 腾讯云 SES
  • Resend(国际服务,对国内支持一般)

参考:SMTP Configuration

第三方登录(OAuth)

GitHub OAuth

  1. 登录 GitHub → Settings → Developer settings → OAuth Apps → New OAuth App
  2. 回调 URL 填:http://你的域名:8000/auth/v1/callback
  3. 获取 Client ID 和 Client Secret
  4. 在 Supabase Studio → Authentication → Providers → GitHub 中填入

Google OAuth

  1. 前往 Google Cloud Console → API 和服务 → 凭据 → 创建 OAuth 2.0 客户端 ID
  2. 回调 URL 同 GitHub
  3. 在 Supabase Studio 中填入 Client ID 和 Secret

微信登录

微信开放平台(open.weixin.qq.com)申请网站应用 → 获取 AppID/AppSecret。

Supabase 目前不内置微信 OAuth,推荐通过以下方式集成:

  • Edge Function 中间层:编写自定义 OAuth provider
  • 第三方 Auth 服务:如 Authing、Casdoor 作为中间层,桥接微信登录和 Supabase Auth

国内短信验证码

Supabase Auth 支持自定义 SMS 提供商,通过 Edge Function 作为中间层调用国内短信 API。

阿里云短信(Aliyun SMS)

  1. 登录阿里云控制台 → 短信服务
  2. 申请签名(需营业执照) → 申请模板
  3. 编写 Edge Function 调用阿里云 SMS API
  4. 在 Supabase Studio → Authentication → SMS Providers → 选择「Custom」→ 填入 Edge Function URL

腾讯云短信(Tencent SMS)

  1. 登录腾讯云控制台 → 短信 → 创建应用
  2. 申请签名和模板
  3. 集成方式同阿里云(Edge Function 中间层)

参考:Phone Login with Supabase Auth

数据表与 RLS 安全

执行迁移

supabase/migrations/ 目录下的 SQL 文件在 Supabase Studio 的 SQL Editor 中逐一执行:

  1. Dashboard → SQL Editor
  2. 粘贴 SQL 文件内容
  3. 点击 Run

自定义 schema 说明

web-nextjs 模板的 SQL 文件使用 __SCHEMA__ 占位符。通过 CLI --schema 参数创建项目时会自动替换。

手动替换方式:在 SQL 文件中全局搜索替换 __SCHEMA__ 为你的 schema 名称(如 myapp),再执行 SQL。

RLS 最佳实践

  • SERVICE_ROLE_KEY 可绕过 RLS(仅在服务端 Route Handler 中使用)
  • anon / authenticated key 必须遵守 RLS 策略
  • 每张表建表后立即启用 RLS:
    ALTER TABLE your_table ENABLE ROW LEVEL SECURITY;

文件存储(Storage)

配置

自部署 Storage 支持以下后端:

  • 本地文件系统.envSTORAGE_BACKEND=file
  • S3 兼容存储(如 MinIO):STORAGE_BACKEND=s3

在 web-nextjs 中使用

// Server Action 中使用 Supabase Storage SDK
import { createClient } from '@supabase/supabase-js'

const supabase = createClient(supabaseUrl, serviceRoleKey)

const { data, error } = await supabase.storage.from('avatars').upload(`${userId}/profile.jpg`, file)

参考:Storage Self-Hosting

数据备份

pg_dump 方式(推荐,最通用)

# 备份(在宿主机执行)
docker exec -t supabase-db pg_dump -U postgres -d postgres > backup_$(date +%Y%m%d_%H%M%S).sql

# 恢复
docker exec -i supabase-db psql -U postgres -d postgres < backup_20250101_000000.sql

Docker volume 备份

直接备份 Docker volume 目录(/var/lib/docker/volumes/supabase_db_data)。

自动化定时备份

# 每天凌晨 3 点自动备份(添加到 crontab)
0 3 * * * docker exec -t supabase-db pg_dump -U postgres -d postgres > /backup/db_$(date +\%Y\%m\%d).sql

Realtime

自部署 Realtime 已包含在 Docker Compose 中(realtime 服务)。

启用表的 Realtime

Dashboard → Database → Replication → 勾选对应表。

在 Next.js 客户端组件中订阅

const channel = supabase
  .channel('payments-changes')
  .on('postgres_changes', { event: 'UPDATE', schema: 'public', table: 'payments' }, (payload) => {
    console.log('Change received!', payload)
  })
  .subscribe()

参考:Realtime Guide

Edge Functions

自部署使用 Deno 运行时(edge-runtime 服务,已在 Docker Compose 中)。

本地开发

supabase functions serve <function-name>

部署到自部署实例

将函数文件放入 supabase/docker/volumes/functions/ 目录后重启 edge-runtime 容器:

docker compose restart edge-runtime

参考:Functions Self-Hosting

AI 功能(pgvector)

启用 pgvector 扩展

在 SQL Editor 中执行:

CREATE EXTENSION IF NOT EXISTS vector;

创建向量列

ALTER TABLE documents ADD COLUMN embedding vector(1536);
CREATE INDEX ON documents USING hnsw (embedding vector_cosine_ops);

在 Server Action 中结合 OpenAI 进行语义检索

'use server'
import OpenAI from 'openai'

const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY })

export async function searchDocuments(query: string) {
  const embedding = await openai.embeddings.create({
    model: 'text-embedding-3-small',
    input: query,
  })

  const { data } = await supabase.rpc('match_documents', {
    query_embedding: embedding.data[0].embedding,
    match_count: 10,
  })

  return data
}

参考:Vector Columns

MCP Server

Supabase MCP Server 让 AI 编程助手(GitHub Copilot、Cursor 等)可以直接操作 Supabase —— 读写数据库、管理表结构。

安装

npx @supabase/mcp-server-supabase@latest

在 VS Code + GitHub Copilot 中配置

创建 .vscode/mcp.json

{
  "servers": {
    "supabase": {
      "command": "npx",
      "args": [
        "-y",
        "@supabase/mcp-server-supabase@latest",
        "--supabase-url",
        "http://localhost:8000",
        "--supabase-key",
        "<your-service-role-key>"
      ]
    }
  }
}

在 Cursor 中配置

编辑 ~/.cursor/mcp.json,内容同上。

参考:Supabase MCP

安全注意事项

  • ⚠️ 生产环境必须修改的默认值:
    • POSTGRES_PASSWORD
    • JWT_SECRET
    • ANON_KEY
    • SERVICE_ROLE_KEY
    • DASHBOARD_USERNAME
    • DASHBOARD_PASSWORD
  • ⚠️ SERVICE_ROLE_KEY 绝不能出现在客户端代码中(不能以 NEXT_PUBLIC_ 开头)
  • ⚠️ 建议在 Supabase 前使用反向代理(Nginx/Traefik)做 SSL 终止,不要直接暴露 8000 端口
  • ⚠️ 定期检查 Docker 镜像更新:
    docker compose pull && docker compose up -d

常见问题(FAQ)

Q: 自部署后收不到邮件? → 检查 SMTP 配置,使用 Inbucket (localhost:54324) 调试。

Q: Studio 无法访问? → 检查 http://localhost:8000 是否通,检查 Docker 端口映射(docker ps)。

Q: RLS 导致查询返回空? → 在 Studio 中检查 policy 定义,或临时用 SERVICE_ROLE_KEY 测试。

Q: auth.users 和自定义表如何关联? → 使用 REFERENCES auth.users(id) ON DELETE CASCADE

Q: 自部署和 Cloud 的 SDK 用法有区别吗? → 无区别,只需将 URL 和 key 换为自部署地址即可。

On this page