Supabase 自部署实战:从入门到精通
Supabase 自部署实战:从入门到精通
在当今快速发展的技术环境中,拥有一个灵活、可扩展的后端解决方案对于开发者来说至关重要。Supabase 作为 Firebase 的开源替代品,提供了完整的后端服务套件,包括 PostgreSQL 数据库、实时订阅、用户认证、文件存储等功能。本文将带您深入了解 Supabase 的自部署过程,从基础配置到生产环境优化,帮助您构建一个完全掌控的后端基础设施。
1. 环境准备与基础部署
1.1 硬件与软件要求
在开始部署 Supabase 之前,确保您的服务器满足以下最低配置要求:
开发/测试环境:
- CPU: 2核
- 内存: 4GB
- 存储: 20GB SSD
生产环境推荐配置:
- CPU: 4-8核
- 内存: 8-16GB
- 存储: 50-100GB SSD
软件依赖:
- 操作系统: Ubuntu 20.04+/Debian 11+/CentOS 8+
- Docker: 20.10+
- Docker Compose: v2.0+
- Git: 用于克隆仓库
1.2 初始部署步骤
让我们从最基本的 Docker 部署开始:
# 克隆 Supabase 官方仓库(浅克隆以加快速度) git clone --depth 1 https://github.com/supabase/supabase # 创建项目目录 mkdir supabase-project # 复制 Docker 配置文件 cp -rf supabase/docker/* supabase-project/ # 复制环境变量模板 cp supabase/docker/.env.example supabase-project/.env # 进入项目目录 cd supabase-project1.3 关键环境变量配置
编辑.env文件,配置以下关键参数:
# 数据库配置 POSTGRES_PASSWORD=your-super-secret-and-long-postgres-password POSTGRES_DB=postgres # JWT 密钥(至少32个字符) JWT_SECRET=your-super-secret-jwt-token-with-at-least-32-characters-long # API 密钥 ANON_KEY=your-anon-key SERVICE_ROLE_KEY=your-service-role-key # 站点 URL(用于认证回调) SITE_URL=http://localhost:3000 # 公开访问 URL SUPABASE_PUBLIC_URL=http://your-domain.com:8000 # Dashboard 认证 DASHBOARD_USERNAME=supabase DASHBOARD_PASSWORD=this_password_is_insecure_and_should_be_updated提示:使用以下命令生成安全的 JWT Secret:
openssl rand -base64 32
2. 域名配置与安全访问
2.1 使用 Nginx 作为反向代理
在生产环境中,我们通常不希望直接暴露 Supabase 服务端口。以下是配置 Nginx 作为反向代理的步骤:
- 安装 Nginx 和 Certbot(用于 SSL 证书):
# Ubuntu/Debian sudo apt update sudo apt install -y nginx certbot python3-certbot-nginx- 创建 Nginx 配置文件
/etc/nginx/sites-available/supabase-api:
server { listen 80; server_name api.yourdomain.com; return 301 https://$server_name$request_uri; } server { listen 443 ssl http2; server_name api.yourdomain.com; ssl_certificate /etc/letsencrypt/live/api.yourdomain.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/api.yourdomain.com/privkey.pem; ssl_protocols TLSv1.2 TLSv1.3; # 安全头部 add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; add_header X-Frame-Options "SAMEORIGIN" always; add_header X-Content-Type-Options "nosniff" always; location / { proxy_pass http://localhost:8000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; # WebSocket 支持 proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } }- 启用配置并重启 Nginx:
sudo ln -s /etc/nginx/sites-available/supabase-api /etc/nginx/sites-enabled/ sudo nginx -t sudo systemctl restart nginx2.2 配置 DNS 记录
在您的域名服务商处添加以下 A 记录:
| 类型 | 名称 | 值 | TTL |
|---|---|---|---|
| A | api | 您的服务器IP | 自动 |
| A | studio | 您的服务器IP | 自动 |
2.3 更新 Supabase 配置
修改.env文件以反映您的域名:
SITE_URL=https://your-frontend-app.com SUPABASE_PUBLIC_URL=https://api.yourdomain.com API_EXTERNAL_URL=https://api.yourdomain.com # 认证相关配置 GOTRUE_SITE_URL=https://your-frontend-app.com GOTRUE_EXTERNAL_URL=https://api.yourdomain.com/auth/v13. 安全加固最佳实践
3.1 修改默认凭证
必须立即修改以下默认凭证:
Dashboard 登录凭证:
DASHBOARD_USERNAME=your-admin-username DASHBOARD_PASSWORD=your-strong-password数据库密码:
POSTGRES_PASSWORD=your-very-strong-database-passwordJWT 密钥:
JWT_SECRET=your-super-secret-jwt-token-with-at-least-32-characters-long
3.2 防火墙配置
使用 UFW 限制不必要的端口访问:
sudo ufw allow 22/tcp # SSH sudo ufw allow 80/tcp # HTTP sudo ufw allow 443/tcp # HTTPS sudo ufw deny 8000/tcp # 禁止直接访问 Kong sudo ufw deny 3000/tcp # 禁止直接访问 Studio sudo ufw deny 5432/tcp # 禁止直接访问 PostgreSQL sudo ufw enable3.3 配置 CORS
在.env中设置允许的来源:
GOTRUE_ADDITIONAL_REDIRECT_URLS=https://your-app.com,https://admin.your-app.com3.4 启用速率限制
编辑volumes/api/kong.yml添加速率限制:
plugins: - name: rate-limiting config: minute: 60 hour: 1000 policy: local4. 生产环境优化
4.1 数据库性能调优
创建volumes/db/postgresql.conf文件进行优化:
# 连接设置 max_connections = 200 # 内存设置 shared_buffers = 2GB effective_cache_size = 6GB maintenance_work_mem = 512MB work_mem = 10MB # WAL 设置 wal_buffers = 16MB min_wal_size = 1GB max_wal_size = 4GB checkpoint_completion_target = 0.9 # 查询优化 default_statistics_target = 100 random_page_cost = 1.1 effective_io_concurrency = 2004.2 使用外部存储
将文件存储配置为使用 S3 兼容服务:
STORAGE_BACKEND=s3 GLOBAL_S3_BUCKET=your-bucket-name REGION=us-east-1 AWS_ACCESS_KEY_ID=your-access-key AWS_SECRET_ACCESS_KEY=your-secret-key4.3 监控设置
添加 Prometheus 和 Grafana 进行监控:
创建docker-compose.monitoring.yml:
version: '3.8' services: prometheus: image: prom/prometheus:latest volumes: - ./prometheus.yml:/etc/prometheus/prometheus.yml - prometheus-data:/prometheus ports: - "9090:9090" grafana: image: grafana/grafana:latest volumes: - grafana-data:/var/lib/grafana ports: - "3001:3000" environment: - GF_SECURITY_ADMIN_PASSWORD=admin volumes: prometheus-data: grafana-data:启动监控服务:
docker compose -f docker-compose.yml -f docker-compose.monitoring.yml up -d5. 备份与恢复策略
5.1 自动化备份脚本
创建backup.sh脚本:
#!/bin/bash BACKUP_DIR="/backups/supabase" DATE=$(date +%Y%m%d_%H%M%S) RETENTION_DAYS=7 mkdir -p $BACKUP_DIR # 备份数据库 docker exec supabase-db pg_dumpall -U postgres > \ $BACKUP_DIR/db_backup_$DATE.sql gzip $BACKUP_DIR/db_backup_$DATE.sql # 备份存储文件 tar -czf $BACKUP_DIR/storage_backup_$DATE.tar.gz \ -C volumes/storage . # 备份配置文件 tar -czf $BACKUP_DIR/config_backup_$DATE.tar.gz \ .env volumes/api/kong.yml # 清理旧备份 find $BACKUP_DIR -name "*.sql.gz" -mtime +$RETENTION_DAYS -delete find $BACKUP_DIR -name "*.tar.gz" -mtime +$RETENTION_DAYS -delete设置定时任务:
chmod +x backup.sh (crontab -l 2>/dev/null; echo "0 2 * * * /path/to/backup.sh >> /var/log/supabase-backup.log 2>&1") | crontab -5.2 恢复流程
停止服务:
docker compose down恢复数据库:
gunzip -c /backups/supabase/db_backup_20241025_020000.sql.gz | \ docker exec -i supabase-db psql -U postgres恢复存储文件:
tar -xzf /backups/supabase/storage_backup_20241025_020000.tar.gz \ -C volumes/storage启动服务:
docker compose up -d
6. 常见问题排查
6.1 服务无法启动
检查服务日志:
docker compose logs -f [service-name]常见原因:
- 端口冲突:检查 8000、3000、5432 端口是否被占用
- 内存不足:至少需要 4GB RAM
- 磁盘空间不足:检查 volumes 目录空间
6.2 数据库连接问题
测试数据库连接:
docker exec -it supabase-db psql -U postgres如果提示密码错误,检查.env中的POSTGRES_PASSWORD设置。
6.3 认证回调失败
确保.env中的以下配置正确:
SITE_URL=https://your-frontend-app.com GOTRUE_SITE_URL=https://your-frontend-app.com GOTRUE_EXTERNAL_URL=https://auth.example.com/auth/v16.4 SMTP 邮件发送失败
Gmail 配置示例:
SMTP_HOST=smtp.gmail.com SMTP_PORT=587 SMTP_USER=your-email@gmail.com SMTP_PASS=your-app-password # 使用应用专用密码,非账户密码 SMTP_SENDER_NAME=Your App Name SMTP_ADMIN_EMAIL=your-email@gmail.com测试 SMTP 连接:
telnet smtp.gmail.com 5877. 维护与升级
7.1 日常维护清单
- 每周:
- 检查磁盘空间使用情况
- 查看日志文件
- 每月:
- 审核安全更新
- 测试备份恢复
- 每季度:
- 检查用户权限
- 性能调优
7.2 监控指标
保持以下指标在健康范围内:
| 指标 | 健康阈值 |
|---|---|
| CPU 使用率 | < 70% |
| 内存使用率 | < 80% |
| 磁盘使用率 | < 85% |
| 数据库连接数 | < max_conn的80% |
| API 响应时间(P95) | < 200ms |
7.3 升级 Supabase 版本
停止服务并备份:
docker compose down ./backup.sh更新代码:
cd supabase git pull origin master复制最新配置文件:
cp -rf docker/* ../supabase-project/更新镜像并启动:
cd ../supabase-project docker compose pull docker compose up -d
