配置反向代理和 HTTPS
Set up a reverse proxy with HTTPS for self-hosted Supabase.
生产环境的自托管 Supabase 部署需要使用 HTTPS。本指南介绍了两种在自托管 Supabase API 网关前使用反向代理的生产环境方法,以及一个用于开发环境的自签名证书选项。
🌐 HTTPS is required for production self-hosted Supabase deployments. This guide covers two production approaches using a reverse proxy in front of self-hosted Supabase API gateway, plus a self-signed certificate option for development environment.
在你开始之前 #
🌐 Before you begin
你需要:
🌐 You need:
- 一个可用的自托管 Supabase 安装。请参阅 使用 Docker 自托管
- 一个域名,DNS 指向你服务器的公网 IP(用于获取 Let's Encrypt 证书)
- 端口 80 和 443 已开放
设置 HTTPS #
🌐 Set up HTTPS
下面有两个选项可以在你自托管的 Supabase 前面添加带自动 HTTPS 的反向代理:Caddy(更简单,无需配置 TLS)和 Nginx + Let's Encrypt(对代理设置有更多控制)。它们都放在 API 网关前面并终止 TLS,所以内部流量仍然使用 HTTP。
🌐 Below are two options for adding a reverse proxy with automatic HTTPS in front of your self-hosted Supabase: Caddy (simpler, zero-config TLS) and Nginx + Let's Encrypt (more control over proxy settings). Both sit in front of the API gateway and terminate TLS, so internal traffic stays on HTTP.
用不同的反向代理吗?
如果你已经在使用 HAProxy、Traefik、Nginx Proxy Manager 或其他反向代理来管理你的基础设施,你可以替代上面提到的 Caddy 或 Nginx。关键要求是:
🌐 If you already run HAProxy, Traefik, Nginx Proxy Manager, or another reverse proxy for your infrastructure, you can use it instead of Caddy or Nginx above. The key requirements are:
- 代理到端口
8000的 API 网关(如果代理在 Docker 网络外运行,则使用<your-ip>:8000) - 启用 WebSocket 支持(实时功能需要)
- 在所有请求中添加
X-Forwarded头 - 如果代理在同一个 Docker 网络中运行,请在
docker-compose.yml中注释掉 API 网关的主机端口绑定 - 在
.env中将SUPABASE_PUBLIC_URL、API_EXTERNAL_URL和SITE_URL更新为你的 HTTPS URL - 查看
volumes/proxy获取示例代理配置文件
用 Envoy 替代 Kong 吗?
Envoy 是一个可选的 API 网关,可以通过 docker-compose.envoy.yml 覆盖来启用。如果你已经运行的是 Envoy 而不是 Kong,编辑 docker-compose.caddy.yml 或 docker-compose.nginx.yml,将 kong: 块注释掉,并取消注释 api-gw: 块(以及匹配的 depends_on 条目),这样反向代理就会位于 Envoy 之前。
🌐 Envoy is an optional API gateway, enabled via the docker-compose.envoy.yml override. If you already run Envoy instead of Kong, edit docker-compose.caddy.yml or docker-compose.nginx.yml to comment out the kong: block and uncomment the api-gw: block (and the matching depends_on entry) so the reverse proxy sits in front of Envoy.
步骤 1:更新环境变量 #
🌐 Step 1: Update environment variables
在你的 .env 文件中更新 URL 配置以使用你的 HTTPS 域名:
🌐 Update the URL configuration in your .env file to use your HTTPS domain:
1SUPABASE_PUBLIC_URL=https://<your-domain>2API_EXTERNAL_URL=https://<your-domain>/auth/v13SITE_URL=https://<your-app-domain>your-app-domain 的意思
<your-app-domain> is the URL of your own frontend application(用户登录后到达的地方)- 不是你的 Supabase 实例。它通常是不同的域名,甚至可能是完全不同的服务,而不是上面使用的 <your-domain>。
对于 Nginx,将以下内容改为你的域名和一个有效的邮箱地址:
🌐 For Nginx, change the following to your domain name and a valid email address:
1PROXY_DOMAIN=your-domain.example.com2CERTBOT_EMAIL=admin@your-domain.example.com第2步:启动反向代理 #
🌐 Step 2: Start the reverse proxy
从下面的选项中选择一个,并使用相应的 Docker Compose 覆盖文件。
🌐 Pick one of the options below and use the corresponding Docker Compose override.
Caddy 可以自动配置和更新 Let's Encrypt TLS 证书,完全不需要设置。它还可以处理 HTTP 到 HTTPS 的重定向、WebSocket 升级,以及开箱即用的 HTTP/2 和 HTTP/3。
启用预配置的 docker-compose.caddy.yml 覆写,然后启动堆栈:
🌐 Enable the pre-configured docker-compose.caddy.yml override, then start the stack:
1sh run.sh config add caddy2sh run.sh startCaddy 的配置在 volumes/proxy/caddy/Caddyfile。
🌐 Caddy configuration is in volumes/proxy/caddy/Caddyfile.
步骤 3:确认 HTTPS 连接 #
🌐 Step 3: Verify HTTPS connection
测试 HTTPS 连接 - 你应该会收到一个 401 响应,确认你可以连接到 Auth:
🌐 Test the HTTPS connection - you should get a 401 response confirming you could connect to Auth:
1curl -I https://<your-domain>/auth/v1/如有需要,查看容器日志(Nginx 使用 supabase-nginx):
🌐 Check container logs if needed (use supabase-nginx for Nginx):
1docker logs supabase-caddy自签名证书(仅限开发使用) #
🌐 Self-signed certificates (development only)
自签名证书会触发浏览器警告,而且大多数 OAuth 提供商都会拒绝它们。这个方法只适合在开发环境或内部网络中使用。
🌐 Self-signed certificates trigger browser warnings and are rejected by most OAuth providers. Use this approach only in development environment or internal networks.
对于不能使用 Let's Encrypt 的开发或内部网络,这里介绍如何配置 Kong(当前的默认 API 网关)使用自签名证书直接提供 HTTPS。
🌐 For development or internal networks where you cannot use Let's Encrypt, here's how you can configure Kong (the current default API gateway) to serve HTTPS directly using self-signed certificates.
第一步:生成自签名证书 #
🌐 Step 1: Generate a self-signed certificate
在下面的例子中更改 <your-domain>,然后使用 openssl 创建证书:
🌐 Change <your-domain> in the example below, and create certificates with openssl:
1openssl req -x509 -nodes -days 365 -newkey rsa:2048 \2 -keyout volumes/api/server.key \3 -out volumes/api/server.crt \4 -subj "/CN=<your-domain>" && \5 chmod 640 volumes/api/server.key && \6 chgrp 65533 volumes/api/server.key第2步:为Kong配置SSL #
🌐 Step 2: Configure Kong for SSL
在 docker-compose.yml 中注释掉 Kong 的 HTTP 端口映射:
🌐 Comment out Kong's HTTP port mapping in docker-compose.yml:
1kong:2 # ...3 ports:4 #- ${KONG_HTTP_PORT}:8000/tcp取消注释 docker-compose.yml 中的证书卷挂载和 SSL 环境变量:
🌐 Uncomment the certificate volume mounts and SSL environment variables in docker-compose.yml:
1kong:2 # ... existing configuration ...3 volumes:4 - ./volumes/api/kong.yml:/home/kong/temp.yml:ro,z5 - ./volumes/api/server.crt:/home/kong/server.crt:ro6 - ./volumes/api/server.key:/home/kong/server.key:ro7 environment:8 # ... existing environment variables ...9 KONG_SSL_CERT: /home/kong/server.crt10 KONG_SSL_CERT_KEY: /home/kong/server.key步骤 3:更新配置变量 #
🌐 Step 3: Update configuration variables
编辑你的 .env 文件,使用 Kong HTTPS 端口的 HTTPS:
🌐 Edit your .env file to use HTTPS with the Kong HTTPS port:
1SUPABASE_PUBLIC_URL=https://<your-domain>:84432API_EXTERNAL_URL=https://<your-domain>:8443/auth/v13SITE_URL=https://<your-app-domain>步骤4:重启并确认 #
🌐 Step 4: Restart and verify
1sh run.sh recreate1curl -I -k https://<your-domain>:8443/auth/v1/-k 标志告诉 curl 接受自签名证书。
🌐 The -k flag tells curl to accept the self-signed certificate.
故障排除 #
🌐 Troubleshooting
证书未发放 #
🌐 Certificate not issued
如果 Caddy 或 Certbot 获取证书失败:
🌐 If Caddy or Certbot fails to obtain a certificate:
- 确认你的防火墙上端口80和443是开放的
- 确认你的域名的 DNS A 记录指向你的服务器公网 IP
- 通过
docker logs supabase-caddy或docker logs supabase-nginx查看代理日志 - Let's Encrypt 有速率限制——如果达到限制,请先等一会再重试
WebSocket 连接失败 #
🌐 WebSocket connection failed
如果实时订阅无法连接:
🌐 If Realtime subscriptions fail to connect:
- Caddy 会自动处理 WebSocket 升级——检查一下 API 网关是否健康
- Nginx 在
/realtime/v1/位置需要明确的Upgrade和Connection头。确认你的nginx.conf包含上面显示的这些头
OAuth 回调 URL 不匹配 #
🌐 OAuth callback URL mismatch
如果 OAuth 重定向因回调 URL 错误而失败:
🌐 If OAuth redirects fail with a callback URL error:
- 确认
.env中的API_EXTERNAL_URL设置为你的 HTTPS URL +/auth/v1 - 确认你在 OAuth 提供商注册的回调 URL 是否与
API_EXTERNAL_URL后跟/callback相匹配 - 更改
API_EXTERNAL_URL后,用sh run.sh recreate重启所有服务
混合内容警告 #
🌐 Mixed content warnings
如果浏览器控制台显示混合内容错误:
🌐 If the browser console shows mixed content errors:
- 确认
SUPABASE_PUBLIC_URL已设置为你的 HTTPS URL - 确认
SITE_URL也设置为 HTTPS - 修改后清理一下浏览器缓存
ERR_CERT_AUTHORITY_INVALID#
使用自签名证书时,这是预期会发生的情况。生产环境中,建议使用带有 Let's Encrypt 的 Caddy 或 Nginx。如果你需要使用自签名证书,把证书添加到系统的信任存储,或者使用浏览器标志来绕过警告。
🌐 This is expected when using self-signed certificates. For production, use Caddy or Nginx with Let's Encrypt. If you need to use self-signed certificates, add the certificate to your system's trust store or use a browser flag to bypass the warning.
额外资源 #
🌐 Additional resources
- Caddy 文档
- Nginx 文档(在 nginx.org 上)
- docker-nginx-certbot 在 GitHub 上