Supabase Docker Compose 部署指南
Supabase v1.26.08 官方自托管编排(Docker Compose)从零部署实录:下载指定版本源码、生成密钥并配置 .env、编排层三处适配(Studio 端口 8100、连接池参数、固定子网)、启动 11 个服务并逐项验证(compose ps 全 healthy、Studio 控制台、API 网关、认证、存储、池化端口),附数据持久化、单容器形态、常用运维命令与常见问题实测。
Supabase Docker Compose 部署指南
目标:从零在 Ubuntu 22.04 服务器上以官方 Docker Compose 编排部署 Supabase v1.26.08 自托管栈,并完成服务健康、控制台、API 网关、认证与数据库池化端口的逐项验证。本文全部命令与回显在实测环境(部署目录
/opt/data/quzuo/supabase-v1.26.08/docker,11 个服务全部 healthy)真实执行并逐字照抄;组件认知与版本背景见《Supabase v1.26.08 介绍与选型指南》。
一、环境信息
本章记录本次部署的目标系统、软件版本与网络端口基准,保证整篇文档的命令与路径可复现。
- 操作系统:Ubuntu 22.04(x86_64)
- 运行时:Docker 29.x(Docker Compose v2 插件);服务器拉取国外镜像较慢时,Docker 守护进程已配置代理
192.168.1.62:7897 - 部署版本:Supabase v1.26.08(GitHub 官方仓库
supabase/supabasetagv1.26.08,2026-08-07 发布) - 部署目录:
/opt/data/quzuo/supabase-v1.26.08/docker(源码仓库的docker/子目录,部署实践保留/opt/data/quzuo/<组件>-<版本>/目录惯例) - 编排项目名:
supabase(compose 文件内name: supabase);自定义网络supabase_default,子网显式固定10.89.29.0/24 - 服务清单(11 个,实测全部 healthy):studio、kong、auth(GoTrue)、rest(PostgREST)、realtime、storage、imgproxy、meta(postgres-meta)、functions(Edge Runtime)、db(PostgreSQL 17.6.1.136)、supavisor(连接池)
- 宿主端口分配(实测
ss -ltn,避开默认 3000/8000 冲突段):
| 宿主端口 | 目标 | 用途 |
|---|---|---|
| 8100 | studio:3000 | Studio 管理控制台 |
| 8101 | kong:8000 | API 网关(HTTP,全部 API 与控制台入口) |
| 8443 | kong:8443 | API 网关(HTTPS) |
| 5433 | supavisor:5432 | 数据库池化连接(会话模式) |
| 6543 | supavisor:6543 | 数据库池化连接(事务模式) |
- 管理凭据(实测环境演示值):控制台账号
admin/q1w2e3r4(.env的DASHBOARD_USERNAME/DASHBOARD_PASSWORD);数据库口令q1w2e3r4(POSTGRES_PASSWORD)。⚠️ 生产环境必须重新生成全部密钥(见四、4.3 节)。 - 系列文档:《Supabase v1.26.08 介绍与选型指南》《Supabase v1.26.08 配置参数详解》《Supabase 日常运维手册》
二、镜像选型说明
官方自托管编排的特点是「一个版本 tag 锁定一组组件镜像」,不需要逐个挑选镜像版本。本章说明镜像来源与锁定策略。
v1.26.08 编排文件内置的镜像与版本如下(从部署目录 docker-compose.yml 实查,与官方 docker/versions.md 记录一致):
| 服务 | 镜像 | 角色 |
|---|---|---|
| db | supabase/postgres:17.6.1.136 | PostgreSQL 17.6 定制发行(内置 pgvector/pgjwt/pg_cron 等扩展与 RLS 初始化) |
| kong | kong/kong:3.9.3 | API 网关(DB-less 声明式配置) |
| auth | supabase/gotrue:v2.189.0 | 认证服务 |
| rest | postgrest/postgrest:v14.12 | REST API 自动生成 |
| realtime | supabase/realtime:v2.102.3 | 实时推送(Elixir) |
| storage | supabase/storage-api:v1.60.4 | 对象存储 API |
| imgproxy | darthsim/imgproxy:v3.30.1 | 图片实时转换 |
| meta | supabase/postgres-meta:v0.96.6 | 数据库元数据 API |
| functions | supabase/edge-runtime:v1.74.0 | 边缘函数运行时(Deno) |
| supavisor | supabase/supavisor:2.9.5 | 连接池(会话/事务模式) |
| studio | supabase/studio:2026.08.03-sha-022b374 | Web 管理控制台 |
关键差异/如何选型:镜像一律使用官方 supabase/* 与编排文件锁定的版本 tag,不要自行升格 latest——Supabase 组件间存在强兼容关系(如 Studio 与 postgres-meta 的接口、GoTrue 与 JWT 密钥格式),整体滚动升级跟随官方新 Release 的编排文件即可(见《Supabase 日常运维手册》升级章节)。另有官方可选叠加编排文件:docker-compose.s3.yml(存储后端换 S3/MinIO)、docker-compose.caddy.yml/docker-compose.nginx.yml(TLS 反代)、docker-compose.pg15.yml/docker-compose.pg17.yml(数据库大版本切换),按需用 -f 叠加。
三、前置条件
部署前确认以下条件全部满足,否则启动会失败或服务不健康:
- 已安装 Docker 与 Compose v2 插件(
docker compose version可执行); - 宿主端口 8100/8101/8443/5433/6543 未被占用(占用时按一、1.1 节端口表同步修改
.env与编排端口); - 服务器可访问外网拉取镜像(或已配置镜像加速/代理);
- 磁盘余量 ≥ 10GB(11 个镜像合计约 4-5GB,数据库数据目录随业务增长);
- 网段规划:编排默认网络的子网将显式固定为
10.89.29.0/24,确认该网段未被占用且不落在192.168.0.0/16(与常见局域网冲突,曾发生过自动分配网段抢占默认路由导致整机断网的事故)与100.64.0.0/16内。
四、部署步骤
本章为从零到可用的完整部署主线:下载官方源码 → 生成密钥配置 .env → 适配端口与子网 → 启动 → 验证。
4.1 下载 v1.26.08 官方源码
从 GitHub 下载指定版本源码(走代理加速,实际部署目录按 /opt/data/quzuo/<组件>-<版本>/ 惯例命名):
export https_proxy=http://192.168.1.62:7897 http_proxy=http://192.168.1.62:7897
cd /opt/data/quzuo && git clone --depth 1 --branch v1.26.08 https://github.com/supabase/supabase.git supabase-v1.26.08
实测回显(克隆完成阶段):
Turn off this advice by setting config variable advice.detachedHead to false
Updating files: 100% (16697/16697), done.
部署只使用其中的 docker/ 子目录(含 docker-compose.yml、.env.example、volumes/ 模板与 utils/ 工具脚本)。确认关键文件存在:
ls /opt/data/quzuo/supabase-v1.26.08/docker/
实测回显(节选):
CHANGELOG.md CONFIG.md docker-compose.yml .env.example README.md
reset.sh run.sh setup.sh update.sh versions.md utils volumes
4.2 生成密钥
官方提供密钥生成脚本 utils/generate-keys.sh,一次性生成 JWT 密钥、API Key、各组件加密密钥与口令:
cd /opt/data/quzuo/supabase-v1.26.08/docker
sh utils/generate-keys.sh
实测回显(每次执行生成的值都不同,以下为其中一次的真实输出,仅作格式示例,部署时应使用自己生成的新值):
JWT_SECRET=JcHBEkBJn2K9KUfnZCM1Ld+QjmESHq19FnppJqFl
ANON_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoiYW5vbiIsImlzcyI6InN1cGFiYXNlIiwiaWF0IjoxNzkyMzg2OTYwLCJleHAiOjE5NTAwNjY5NjB9.jSiHmr6hWr3B364XPxuTjTvpm7wJfxsTNiBEpGdL6-Q
SERVICE_ROLE_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoic2VydmljZV9yb2xlIiwiaXNzIjoic3VwYWJhc2UiLCJpYXQiOjE3OTIzODY5NjAsImV4cCI6MTk1MDA2Njk2MH0.G6U7dhPl3jCHM8YLy-whm5C-wjnodoeccJ3MuRNx6HA
SECRET_KEY_BASE=qr3OQuxn7BvDcHRgGdz0zJd9uehPY5p21uc/nw9a2M8MuFSASHyJiWHd8AO2gCE8
REALTIME_DB_ENC_KEY=42dc32f685daaf50
VAULT_ENC_KEY=1e92648b1746072a9daf6b10d769cfb6
PG_META_CRYPTO_KEY=ZsaabygOzrcPYv8oggnKsm7czKchK4/Q
LOGFLARE_PUBLIC_ACCESS_TOKEN=LVeXcIFbqySnTgUgT7hC6sz3AZ6P9vlG
LOGFLARE_PRIVATE_ACCESS_TOKEN=ODZE8DynURvlj6JAmOmzRNEt2NlE4o1S
S3_PROTOCOL_ACCESS_KEY_ID=10d8073349d40c9304b0635254469faa
S3_PROTOCOL_ACCESS_KEY_SECRET=25a82bd67597c8af11731a940fee6b3be66e74321fcb8f5ab2c90af4de5bc63d
MINIO_ROOT_PASSWORD=4fb1ed7f544039a4a8c60711fe63e469
POSTGRES_PASSWORD=55adca05f0e48505d0e2b55c2cf2de4b
DASHBOARD_PASSWORD=374763090260fc63b2460ef1e4c484f9
Running non-interactively. Pass --update-env to write to .env.
💡 说明:脚本提示
Pass --update-env to write to .env——交互模式下会直接把新密钥写进.env;非交互(管道)模式只打印。也可手动执行sh utils/generate-keys.sh --update-env让脚本直接改写.env。配套的utils/add-new-auth-keys.sh用于叠加新的非对称 API 密钥(ES256),前置要求.env已存在,在空目录执行会报Error: .env file not found. Run generate-keys.sh first.(实测)。
4.3 配置 .env(密钥、URL 与端口)
以官方示例为底本生成配置,再填入 4.2 节生成的密钥:
cd /opt/data/quzuo/supabase-v1.26.08/docker
cp .env.example .env
需要修改的关键项及实测环境取值(完整键位讲解见《Supabase v1.26.08 配置参数详解》):
| 键 | 实测值 | 说明 |
|---|---|---|
| POSTGRES_PASSWORD | q1w2e3r4 | 数据库超级用户口令(实验环境演示值,生产用 4.2 节生成值) |
| JWT_SECRET | Tp5n55aRTXPaBF+hAs0/Xoydu/ExMmSXqWcutGRQ | HS256 签名密钥(≥32 字符) |
| ANON_KEY / SERVICE_ROLE_KEY | (4.2 节生成的 HS256 JWT,见 .env) | 公开 anon 与服务端 service_role 两把 API Key |
| DASHBOARD_USERNAME / DASHBOARD_PASSWORD | admin / q1w2e3r4 | Studio 控制台登录凭据 |
| SUPABASE_PUBLIC_URL | http://192.168.146.128:8101 | 对外服务地址(网关端口) |
| API_EXTERNAL_URL | http://192.168.146.128:8101/auth/v1 | 认证服务外部地址(OAuth 回调/邮件链接依赖它) |
| SITE_URL | http://192.168.146.128:8101 | 认证重定向的主站地址 |
| POSTGRES_PORT | 5433 | 池化会话端口(宿主侧) |
| POOLER_PROXY_PORT_TRANSACTION | 6543 | 池化事务端口(宿主侧) |
| KONG_HTTP_PORT / KONG_HTTPS_PORT | 8101 / 8443 | 网关 HTTP/HTTPS 端口(默认 8000/8443,8000 被占改 8101) |
⚠️ 三个 URL 键(SUPABASE_PUBLIC_URL/API_EXTERNAL_URL/SITE_URL)必须改成「访问本栈所用的真实地址:网关端口」,否则 OAuth 回调、邮件确认链接会指向错误地址。
4.4 编排文件适配(端口、子网与实测差异)
官方原版编排默认把 Studio 暴露在容器网络内(仅经网关访问)。本环境做三处适配,以下为实测环境部署目录与官方 v1.26.08 原版的完整差异(diff 实测结果):
- Studio 独立端口:
studio服务增加ports: ["8100:3000/tcp"],使控制台可直连 8100 访问(网关 8101 上的控制台路由另有 basic-auth 保护,实测见十一、11.5 节); - 连接池文件句柄:
supavisor服务环境增加RLIMIT_NOFILE: "10000"; - 显式固定子网:文件末尾追加网络配置,固定子网并避开易冲突网段:
networks:
default:
ipam:
config:
- subnet: 10.89.29.0/24
4.5 启动
cd /opt/data/quzuo/supabase-v1.26.08/docker
docker compose up -d
首次启动会自动拉取 11 个镜像(服务器已配置镜像代理,无需手动加速),随后按依赖顺序启动:db 最先(其余服务 depends_on: db: condition: service_healthy),kong 等 studio 健康后再启动。约 1-2 分钟后全部进入 healthy。
4.6 验证
(1)服务状态核验——11 个服务全部 healthy 才算部署成功:
docker compose ps --format 'table {{.Name}}\t{{.Service}}\t{{.Status}}'
实测回显:
NAME SERVICE STATUS
realtime-dev.supabase-realtime realtime Up 4 hours (healthy)
supabase-auth auth Up 4 hours (healthy)
supabase-db db Up 4 hours (healthy)
supabase-edge-functions functions Up 4 hours (healthy)
supabase-imgproxy imgproxy Up 4 hours (healthy)
supabase-kong kong Up 4 hours (healthy)
supabase-meta meta Up 4 hours (healthy)
supabase-pooler supavisor Up 4 hours (healthy)
supabase-rest rest Up 4 hours (healthy)
supabase-storage storage Up 4 hours (healthy)
supabase-studio studio Up 4 hours (healthy)
💡 说明:realtime 服务的容器名为
realtime-dev.supabase-realtime,与container_name定义一致(Realtime 按子域名解析租户,官方命名如此,非异常)。
(2)宿主端口核验:
ss -ltn | grep -E ':(8100|8101|8443|5433|6543)\s'
实测回显:
LISTEN 0 4096 0.0.0.0:5433 0.0.0.0:*
LISTEN 0 4096 0.0.0.0:6543 0.0.0.0:*
LISTEN 0 4096 0.0.0.0:8100 0.0.0.0:*
LISTEN 0 4096 0.0.0.0:8101 0.0.0.0:*
LISTEN 0 4096 0.0.0.0:8443 0.0.0.0:*
LISTEN 0 4096 [::]:5433 [::]:*
LISTEN 0 4096 [::]:6543 [::]:*
LISTEN 0 4096 [::]:8100 [::]:*
LISTEN 0 4096 [::]:8101 [::]:*
LISTEN 0 4096 [::]:8443 [::]:*
(3)Studio 控制台——根路径 307 跳转到默认项目页,项目页返回 200:
curl -s -o /dev/null -w 'root=%{http_code} redirect=%{redirect_url}\n' http://127.0.0.1:8100/
curl -s -o /dev/null -w 'project=%{http_code}\n' http://127.0.0.1:8100/project/default
实测回显:
root=307 redirect=http://127.0.0.1:8100/project/default
project=200
浏览器打开 http://192.168.146.128:8100/project/default,用 admin / q1w2e3r4 登录控制台即部署完成。
(4)API 网关与各端点(anon key 取自 .env 的 ANON_KEY):
ANON=$(grep '^ANON_KEY=' .env | cut -d= -f2)
curl -s -w '\nhttp=%{http_code}\n' "http://127.0.0.1:8101/auth/v1/health" -H "apikey: $ANON" | tail -3
curl -s -o /dev/null -w 'storage-status=%{http_code}\n' http://127.0.0.1:8101/storage/v1/status
实测回显:
{"version":"v2.189.0","name":"GoTrue","description":"GoTrue is a user registration and authentication API"}
http=200
storage-status=200
(5)数据库池化端口——用户名必须带租户标识 postgres.<POOLER_TENANT_ID>(默认租户 id 为 your-tenant-id),否则连接被拒:
PGPASSWORD=q1w2e3r4 psql -h 127.0.0.1 -p 5433 -U postgres.your-tenant-id -d postgres -tAc "select 'session-ok', current_user;"
PGPASSWORD=q1w2e3r4 psql -h 127.0.0.1 -p 6543 -U postgres.your-tenant-id -d postgres -tAc "select 'tx-ok', current_user;"
实测回显:
session-ok|postgres|postgres
tx-ok|postgres
(6)认证全链路——注册与登录(邮箱已启用自动确认,ENABLE_EMAIL_AUTOCONFIRM=true):
ANON=$(grep '^ANON_KEY=' .env | cut -d= -f2)
curl -s -X POST "http://127.0.0.1:8101/auth/v1/token?grant_type=password" \
-H "apikey: $ANON" -H 'Content-Type: application/json' \
-d '{"email":"admin@example.com","password":"q1w2e3r4"}' \
| python3 -c "import json,sys; d=json.load(sys.stdin); print('token_type=',d.get('token_type'),'| expires_in=',d.get('expires_in'),'| user.email=',d.get('user',{}).get('email'),'| role=',d.get('user',{}).get('role'))"
实测回显:
token_type= bearer | expires_in= 3600 | user.email= admin@example.com | role= authenticated
验证结论:11 服务 healthy、5 个宿主端口监听、控制台 200、认证/存储端点 200、双池化端口可连、JWT 登录签发正常——部署成功。
五、数据持久化说明
Supabase 的持久化分「宿主绑定目录」与「命名数据卷」两类,全部位于部署目录下,升级/迁移时整体打包这两类即可:
(1)宿主绑定目录 volumes/(实测目录与占用):
| 目录 | 挂载点 | 内容 |
|---|---|---|
volumes/db/data | /var/lib/postgresql/data | PostgreSQL 数据目录(实测 67MB,业务数据主体) |
volumes/db/*.sql | docker-entrypoint-initdb.d/ | 首次初始化 SQL(roles/webhooks/jwt/realtime/pooler/logs 等,仅在数据目录为空时执行) |
volumes/api/kong.yml | /home/kong/temp.yml | 网关声明式路由(环境变量替换后生效) |
volumes/pooler/pooler.exs | /etc/pooler/pooler.exs | 连接池租户配置 |
volumes/storage | /var/lib/storage | 对象存储文件(STORAGE_BACKEND=file) |
volumes/functions | 边缘函数目录 | 部署的 Edge Functions |
volumes/snippets | Studio 代码片段 | SQL 代码片段 |
volumes/logs、volumes/proxy | 日志/反代 | 日志分析栈与 TLS 反代(默认编排未启用) |
实测体积(du -sh,部署初期):volumes/ 合计 68M,其中 volumes/db/data 67M。
(2)命名数据卷:db-config(pgsodium 解密密钥等 PostgreSQL 自定义配置,/etc/postgresql-custom)、deno-cache(边缘函数依赖缓存)。⚠️ 这两个卷不随 volumes/ 目录打包,迁移时需 docker run --rm -v supabase_db-config:/data alpine tar czf - /data 类命令导出(或直接整体 docker run 导出卷内容)。
(3)备份要点:数据库用 pg_dump/pg_restore 逻辑备份,数据目录冷备需先停服务再复制(避免热拷贝损坏),完整备份/恢复流程见《Supabase 日常运维手册》。
六、环境变量表
.env 是整个栈唯一的集中配置入口(编排文件通过 ${VAR} 引用)。下表为实测环境的关键键位与取值(密钥类为实验环境演示值,⚠️ 生产必须重新生成):
6.1 密钥与凭据类
| 键 | 实测值(演示) | 用途与消费方 |
|---|---|---|
| POSTGRES_PASSWORD | q1w2e3r4 | 数据库口令;auth/rest/realtime/storage/meta/pooler/functions 全部经它连库 |
| JWT_SECRET | Tp5n55aRTXPaBF+hAs0/Xoydu/ExMmSXqWcutGRQ | HS256 对称密钥;签发/校验 JWT(auth 签发,rest/realtime/storage/functions 校验) |
| ANON_KEY | eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoiYW5vbiIsImlzcyI6InN1cGFiYXNlIiwiaWF0IjoxNzkyMzcwMzg3LCJleHAiOjE5NTAwNTAzODd9.9NcAn-RwBqLBEd6vWBf658Rete8N2cHCbcp0hdkhRSM | 匿名角色 JWT 形态 API Key(可暴露给前端) |
| SERVICE_ROLE_KEY | eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoic2VydmljZV9yb2xlIiwiaXNzIjoic3VwYWJhc2UiLCJpYXQiOjE3OTIzNzAzODcsImV4cCI6MTk1MDA1MDM4N30.XMmAQ4VUhcJirwg9sznihzxjqrCl5EFakDKe5804Zek | service_role 角色 API Key(绕过 RLS,仅服务端,严禁泄露) |
| DASHBOARD_USERNAME / DASHBOARD_PASSWORD | admin / q1w2e3r4 | 控制台凭据(网关 basic-auth 消费) |
| SECRET_KEY_BASE | P6oY6yiKadIigQwaVKPucJgSu+4qkLNQv2/+1g/VWib1bUAzRdz3y5Y165hMskI3 | Realtime 与 Supavisor 通信加密(≥64 字符) |
| REALTIME_DB_ENC_KEY | fd4b646feefad5f1 | Realtime 敏感字段加密(16 字符) |
| VAULT_ENC_KEY | 746f76ba1bf4650693468a46849cfdc7 | 连接池加密配置存储(32 字符) |
| PG_META_CRYPTO_KEY | /fyfoqRcv+HHnTBrONeoKgPrlltJRrv7 | Studio↔postgres-meta 连接串加密(≥32 字符) |
| LOGFLARE_PUBLIC_ACCESS_TOKEN / LOGFLARE_PRIVATE_ACCESS_TOKEN | T0setSss2hwNVjbGz0rHkxCy44CMKcm7 / fCj2uEhxSz9tYc/zBQHNSooomNyihzml | 日志摄取/管理令牌(启用日志分析栈时生效) |
| S3_PROTOCOL_ACCESS_KEY_ID / S3_PROTOCOL_ACCESS_KEY_SECRET | 7469fd91958cb618393e26aeb608a715 / b22000115fac5e35320a8d509a2a50be4ae423028f3f301d850f07947ec44b57 | 存储 S3 协议端点凭据 |
| SUPABASE_PUBLISHABLE_KEY / SUPABASE_SECRET_KEY / JWT_KEYS / JWT_JWKS | (空) | 新版不透明 API Key 与 ES256 JWK(留空走 HS256 旧体系) |
6.2 URL 与端口类
| 键 | 实测值 | 说明 |
|---|---|---|
| SUPABASE_PUBLIC_URL | http://192.168.146.128:8101 | 对外统一地址(控制台/存储公开 URL 消费) |
| API_EXTERNAL_URL | http://192.168.146.128:8101/auth/v1 | 认证外部地址(OAuth 回调、邮件链接) |
| SITE_URL | http://192.168.146.128:8101 | 认证重定向主站 |
| ADDITIONAL_REDIRECT_URLS | (空) | 额外允许的重定向白名单 |
| POSTGRES_HOST / POSTGRES_DB / POSTGRES_PORT | db / postgres / 5433 | 栈内数据库地址与池化端口 |
| POOLER_PROXY_PORT_TRANSACTION | 6543 | 事务池化端口 |
| KONG_HTTP_PORT / KONG_HTTPS_PORT | 8101 / 8443 | 网关宿主端口 |
| STUDIO_DEFAULT_ORGANIZATION / STUDIO_DEFAULT_PROJECT | Default Organization / Default Project | 控制台默认组织/项目名 |
6.3 认证行为类
| 键 | 实测值 | 说明 |
|---|---|---|
| JWT_EXPIRY | 3600 | JWT 有效期(秒),实测登录响应 expires_in=3600 |
| DISABLE_SIGNUP | false | 关闭注册开关 |
| ENABLE_EMAIL_SIGNUP / ENABLE_EMAIL_AUTOCONFIRM | true / true | 邮箱注册与自动确认(免 SMTP 验证邮件) |
| SMTP_HOST / SMTP_PORT / SMTP_ADMIN_EMAIL | supabase-mail / 2500 / admin@example.com | 自定义 SMTP(默认指向可选邮件组件,未启用时邮件功能不可外发) |
| ENABLE_PHONE_SIGNUP / ENABLE_PHONE_AUTOCONFIRM | true / true | 手机号注册与自动确认 |
| FUNCTIONS_VERIFY_JWT | false | 边缘函数全局 JWT 校验开关 |
6.4 API 与存储类
| 键 | 实测值 | 说明 |
|---|---|---|
| PGRST_DB_SCHEMAS | public,graphql_public | REST 暴露的模式 |
| PGRST_DB_MAX_ROWS | 1000 | 单请求最大返回行数(修改实测见《Supabase v1.26.08 配置参数详解》) |
| PGRST_DB_EXTRA_SEARCH_PATH | public | 请求 search_path 附加模式 |
| GLOBAL_S3_BUCKET / REGION / STORAGE_TENANT_ID | stub / stub / stub | 存储桶与租户占位(STORAGE_BACKEND=file 下用默认值即可) |
| IMGPROXY_AUTO_WEBP | true | 图片自动 WebP 转换 |
七、配置参数说明
各服务的调优参数集中在两处:.env(全栈共享)与编排文件 environment:(组件私有)。常用可调项与建议:
- 连接池容量:
POOLER_DEFAULT_POOL_SIZE(每池默认 20,池到 PostgreSQL 的实际连接数)、POOLER_MAX_CLIENT_CONN(实测 100,客户端侧最大连接)、POOLER_DB_POOL_SIZE(池化服务自身元数据库连接,实测 5)。高并发短连接场景提高前两者;事务模式(6543)吞吐高于会话模式(5433),但事务模式禁用会话级特性(如SET、预编译语句复用)。 - REST 行数上限:
PGRST_DB_MAX_ROWS默认 1000,防全表拖库;配合分页(Range头)使用,修改方法与生效验证见《Supabase v1.26.08 配置参数详解》。 - 存储单文件上限:编排内
FILE_SIZE_LIMIT: 52428800(50MB),大文件场景在编排文件中调整。 - JWT 有效期:
JWT_EXPIRY(3600 秒),缩短可降低令牌被盗用窗口,客户端需配合刷新令牌机制。 - 网关缓冲:编排内
KONG_NGINX_PROXY_PROXY_BUFFER_SIZE: 160k,大响应头/大 JWT 场景才需要调大。
⚠️ 注意:修改
.env后必须docker compose up -d让受影响服务按新变量重建;docker compose restart只重启进程、不会重读 .env(实测验证,见十一、11.2 节)。
八、配置文件挂载
编排通过绑定挂载注入三类配置文件,修改后按对应服务的重建方式生效:
| 文件(部署目录相对路径) | 挂载目标 | 修改后生效方式 |
|---|---|---|
volumes/api/kong.yml | kong 声明式路由 | docker compose restart kong(网关每次启动重读声明式配置) |
volumes/api/kong-entrypoint.sh | kong 启动脚本(做环境变量替换) | docker compose up -d kong 重建 |
volumes/pooler/pooler.exs | 连接池租户定义 | docker compose up -d supavisor 重建 |
volumes/db/*.sql | 数据库首次初始化脚本 | 仅数据目录为空时执行;已有数据请手动执行 SQL |
volumes/functions/* | 边缘函数源码 | 重新部署函数 |
volumes/snippets/ | Studio SQL 片段 | 即时生效 |
Kong 路由文件 volumes/api/kong.yml 的要点(完整路由表与鉴权规则讲解见《Supabase v1.26.08 配置参数详解》):消费方 anon/service_role 绑定 API Key 与 ACL 组,DASHBOARD 消费方绑定控制台 basic-auth 凭据;/rest/v1/、/auth/v1/、/realtime/v1/ 挂 key-auth 插件,/storage/v1/、/functions/v1/ 免 API Key;/api/mcp 与 Realtime 管理端点默认用 request-termination 插件封禁(403)。
九、单容器形态(等价 docker run 替代说明)
Supabase 官方不提供 all-in-one 单容器镜像——11 个服务是强依赖组合(认证/REST/实时/存储全部直连数据库,网关统一入口),单容器跑全栈没有官方支持路径。本节按「最小形态」给出两个可落地的单容器用法:
(1)最小可用裁剪:仅保留 db + auth + rest + kong + studio 五个服务即可获得「数据库 + 认证 + REST API + 控制台」核心能力(放弃实时/存储/函数),方法是在 docker-compose.yml 中注释掉其余服务段落后 docker compose up -d。此形态仍为多服务编排,适合资源紧张的演示环境。
(2)数据库镜像单独使用:supabase/postgres 镜像是标准 PostgreSQL 入口,可脱离编排单独运行,相当于「内置 Supabase 扩展全家桶的 PostgreSQL 17 单容器」。实测:
docker run -d --name supabase-postgres-17-6-standalone \
-e POSTGRES_PASSWORD=q1w2e3r4 \
-p 127.0.0.1:15433:5432 \
supabase/postgres:17.6.1.136
docker ps --filter name=supabase-postgres-17-6-standalone --format '{{.Names}}\t{{.Status}}'
实测回显:
supabase-postgres-17-6-standalone Up 6 seconds (healthy)
验证内置扩展(已安装扩展与可安装扩展两次实查):
PGPASSWORD=q1w2e3r4 psql -h 127.0.0.1 -p 15433 -U postgres -d postgres -tAc "select extname from pg_extension order by 1;"
实测回显:
pg_stat_statements
pgcrypto
plpgsql
supabase_vault
uuid-ossp
PGPASSWORD=q1w2e3r4 psql -h 127.0.0.1 -p 15433 -U postgres -d postgres -tAc "select name from pg_available_extensions where name in ('pgcrypto','uuid-ossp','pgjwt','pg_stat_statements','pg_cron') order by 1;"
实测回显:
pg_cron
pg_stat_statements
pgcrypto
pgjwt
uuid-ossp
结论:该镜像可独立作为「带 Supabase 扩展的 PostgreSQL」使用(向量、加密、JWT、定时任务扩展齐备),但它只是数据底座,不包含认证/API 网关/控制台能力;完整 BaaS 能力仍需完整编排。
十、常用运维命令
以下命令均在部署目录 /opt/data/quzuo/supabase-v1.26.08/docker 下执行:
# 服务状态(含健康检查结果)
docker compose ps
# 启动 / 停止 / 重启全部服务
docker compose up -d
docker compose down # 加 -v 会连命名数据卷一并删除,慎用
docker compose restart
# 查看某服务日志(实时跟踪)
docker compose logs -f --tail 100 kong
docker compose logs -f --tail 100 db
# 修改 .env 后使配置生效(重建受影响服务)
docker compose up -d
# 仅重建单个服务(实测示例:rest)
docker compose up -d rest
# 进入数据库执行 SQL
docker exec -it supabase-db psql -U postgres
# 资源占用快照
docker stats --no-stream | grep supabase
实测回显(docker compose ps 与日志样例见 4.6 节与 11.1 节;docker stats 输出随负载变化,此处不固化)。
十一、常见问题(FAQ)
11.1 连接池化端口报 FATAL (ENOIDENTIFIER)
现象(实测原始报错):
psql: 错误: 连接到"127.0.0.1"上的服务器,端口5433失败:FATAL: (ENOIDENTIFIER) no tenant identifier provided (external_id or sni_hostname required)
原因:5433/6543 是 Supavisor 连接池端口,池化服务按租户路由,要求用户名形如 <数据库用户>.<租户ID>。解决:用户名改为 postgres.<POOLER_TENANT_ID>(默认租户 ID 为 .env 中的 your-tenant-id),见 4.6 节(5)的实测成功连接。
11.2 修改 .env 后 restart 不生效
现象:docker compose restart 后新变量未生效。原因:restart 只重启进程,环境变量在容器创建时注入。解决(实测):改用 docker compose up -d,Compose 会检测到配置变化自动重建受影响服务(实测修改 PGRST_DB_MAX_ROWS 后 docker compose up -d rest,回显含 Recreate → Recreated → Started,新值立即生效)。
11.3 网关状态端点 401
现象(实测):curl http://127.0.0.1:8101/kong/status 无论是否携带 apikey 均返回 401 {"message":"Unauthorized",...}。说明:该端点非公开探活端点。解决:探活改用 GET /auth/v1/health(携 anon key 返回 200 与 GoTrue 版本 JSON)或 GET /storage/v1/status(免鉴权 200)。
11.4 Studio 根路径 307 跳转
现象:curl http://127.0.0.1:8100/ 返回 307,Location: http://127.0.0.1:8100/project/default。结论:这是控制台默认跳转到默认项目页的正常行为,跟随重定向即为 200(见 4.6 节(3)实测),不是故障。
11.5 经网关访问控制台 401
现象:不带凭据访问 http://127.0.0.1:8101/ 返回 401。原因:网关的控制台路由挂载 basic-auth 插件(消费方 DASHBOARD)。验证(实测):curl -u admin:q1w2e3r4 http://127.0.0.1:8101/ 返回 307;直接用 8100 端口访问控制台则无此层鉴权。生产环境建议只暴露网关 8101(保留 basic-auth),不对外发布 8100。
11.6 注册报 422 user_already_exists
现象(实测):POST /auth/v1/signup 返回 {"code":422,"error_code":"user_already_exists","msg":"User already registered"}。原因:邮箱已注册。解决:换邮箱或直接用密码登录(grant_type=password)。
11.7 端口冲突与子网规划
默认编排的 8000/3000 端口极易与常见服务冲突,本环境改为 8100/8101/8443(一、1.1 节端口表);自定义网络显式固定 10.89.29.0/24(4.4 节),避免自动分配撞上 192.168.0.0/16 物理网段导致路由异常。
十二、参考链接
- 官方自托管 Docker 指南(本篇部署主线的官方依据):https://supabase.com/docs/guides/self-hosting/docker
- 自托管安全配置(密钥与 API Key 生成):https://supabase.com/docs/guides/self-hosting/docker#configuring-and-securing-supabase
- 官方仓库 docker 目录与编排文件(v1.26.08):https://github.com/supabase/supabase/tree/v1.26.08/docker
- v1.26.08 Release 页:https://github.com/supabase/supabase/releases/tag/v1.26.08
- 池化连接说明(Supavisor 两种模式):https://supabase.com/docs/guides/self-hosting/docker#accessing-postgres-through-supavisor
- 系列文档:《Supabase v1.26.08 介绍与选型指南》《Supabase v1.26.08 配置参数详解》《Supabase 日常运维手册》