目录
Sub2API Docker 部署指南
Sub2API 是一款开源的 AI API 网关平台,用于分发和管理 AI 产品订阅的 API 配额。它支持多账号管理(OAuth、API Key)、Token 级精确计费、智能调度和并发控制,适合作为 NewAPI 等下游网关的上游渠道。
本文记录在 VPS 上使用 Docker Compose 部署 Sub2API,并通过 nginx + Cloudflare Origin CA 配置 HTTPS 反向代理的完整过程。Sub2API 仅作为 NewAPI 的内部上游使用,不直接对外开放。
环境准备
前期需要准备:
- 一台 VPS(本文以 Debian 12 为例)
- 一个托管在 Cloudflare 的域名(需通配符 SSL 证书或单独生成子域名证书)
- 服务器已安装 Docker 和 Docker Compose
- 服务器已安装 nginx
第一步:创建项目目录
在服务器上创建 Sub2API 的数据目录:
mkdir -p /root/sub2api
第二步:编写 Docker Compose 配置
创建 `/root/sub2api/docker-compose.yml`:
services: sub2api: image: weishaw/sub2api:latest container_name: sub2api restart: unless-stopped ports: - "${BIND_HOST:-127.0.0.1}:${SERVER_PORT:-8081}:8080" volumes: - sub2api_data:/app/data environment: - AUTO_SETUP=true - SERVER_PORT=8080 - TZ=Asia/Shanghai # PostgreSQL - DATABASE_HOST=postgres - DATABASE_PORT=5432 - DATABASE_USER=${POSTGRES_USER:-sub2api} - DATABASE_PASSWORD=${POSTGRES_PASSWORD} - DATABASE_DBNAME=${POSTGRES_DB:-sub2api} - DATABASE_SSLMODE=disable # Redis - REDIS_HOST=redis - REDIS_PORT=6379 - REDIS_PASSWORD= - REDIS_DB=0 # Admin - ADMIN_EMAIL=${ADMIN_EMAIL:[email protected]} - ADMIN_PASSWORD=${ADMIN_PASSWORD:-} # JWT(必须固定,否则每次重启导致登录失效) - JWT_SECRET=${JWT_SECRET} - TOTP_ENCRYPTION_KEY=${TOTP_ENCRYPTION_KEY} # 安全配置(内部使用,允许 HTTP) - SECURITY_URL_ALLOWLIST_ENABLED=false - SECURITY_URL_ALLOWLIST_ALLOW_INSECURE_HTTP=true - SECURITY_URL_ALLOWLIST_ALLOW_PRIVATE_HOSTS=true depends_on: postgres: condition: service_healthy redis: condition: service_healthy networks: - sub2api-network postgres: image: postgres:18-alpine container_name: sub2api-postgres restart: unless-stopped volumes: - postgres_data:/var/lib/postgresql/data environment: - PGDATA=/var/lib/postgresql/data - POSTGRES_USER=${POSTGRES_USER:-sub2api} - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} - POSTGRES_DB=${POSTGRES_DB:-sub2api} - TZ=Asia/Shanghai networks: - sub2api-network healthcheck: test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-sub2api} -d ${POSTGRES_DB:-sub2api}"] interval: 10s timeout: 5s retries: 5 start_period: 10s redis: image: redis:8-alpine container_name: sub2api-redis restart: unless-stopped volumes: - redis_data:/data command: redis-server --save 60 1 --appendonly yes environment: - TZ=Asia/Shanghai networks: - sub2api-network healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 5 start_period: 5s volumes: sub2api_data: postgres_data: redis_data: networks: sub2api-network: driver: bridge
第三步:配置环境变量
创建 `/root/sub2api/.env`:
# 服务器绑定 BIND_HOST=127.0.0.1 SERVER_PORT=8081 SERVER_MODE=release TZ=Asia/Shanghai # PostgreSQL POSTGRES_USER=sub2api POSTGRES_PASSWORD=<设置一个强密码> POSTGRES_DB=sub2api # 管理员(留空密码则首次启动自动生成) ADMIN_EMAIL=admin@sub2api.local ADMIN_PASSWORD= # 密钥(必须固定,否则每次重启会话失效) JWT_SECRET=<openssl rand -hex 32 生成> TOTP_ENCRYPTION_KEY=<openssl rand -hex 32 生成>
关键说明:
- 端口映射:容器内部监听 8080,宿主机映射到 8081,绑定 `127.0.0.1` 避免直接暴露到公网
- JWT_SECRET:必须固定,否则每次容器重启所有用户登录失效。用 `openssl rand -hex 32` 生成
- TOTP_ENCRYPTION_KEY:同上,用于双因素认证加密,必须固定
- ADMIN_PASSWORD:留空则首次启动时自动生成,密码在日志中输出,仅显示一次
第四步:启动容器
cd /root/sub2api docker compose pull docker compose up -d
检查容器状态:
docker ps --filter name=sub2api --format 'table {{.Names}}\t{{.Status}}\t{{.Ports}}'
确认所有容器均为 healthy。首次启动时 Sub2API 会自动初始化数据库并创建管理员账号。查看管理员密码:
docker logs sub2api 2>&1 | grep -i 'admin password'
输出类似:
Generated admin password (one-time): 66c159b728f3b49f9537078c9a1367d6
第五步:配置 Nginx 反向代理
如果仅需内部使用(如供给同一台 VPS 上的 NewAPI),可跳过这一步,直接使用 `http://127.0.0.1:8081`。
如需通过域名访问管理后台,创建 `/etc/nginx/sites-enabled/sub2api`:
server { listen 80; listen [::]:80; server_name sub2api.your-domain.example.com; return 301 https://$host$request_uri; } server { listen 443 ssl; listen [::]:443 ssl; server_name sub2api.your-domain.example.com; ssl_certificate /etc/ssl/your-cert.crt; ssl_certificate_key /etc/ssl/your-cert.key; ssl_protocols TLSv1.2 TLSv1.3; underscores_in_headers on; client_max_body_size 20M; location / { proxy_pass http://127.0.0.1:8081; 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; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } }
注意: `underscores_in_headers on;` 必须添加,否则 Nginx 默认会丢弃名称中带下划线的请求头(如 `session_id`),导致 Sub2API 的粘性会话功能失效。
测试并重载 nginx:
nginx -t nginx -s reload
第六步:配置 DNS 和 SSL
在 Cloudflare 的 DNS 设置中添加 A 记录:
- 类型:A
- 名称:sub2api(或你选择的子域名)
- 目标:你的 VPS IP 地址
- 代理:开启(橙色云朵)
SSL 证书推荐使用 Cloudflare Origin CA:
- 登录 Cloudflare Dashboard,进入目标域名的 SSL/TLS → Origin Server
- 点击 Create Certificate
- 私钥类型选择 RSA(2048),主机名包含目标子域名
- 有效期选择 15 年
- 将 Origin Certificate 和 Private Key 保存到服务器的 `/etc/ssl/` 目录
- 设置私钥权限:`chmod 640 /etc/ssl/your-cert.key`
- 在 Cloudflare 中将 SSL/TLS 加密模式设为 Full (Strict)
第七步:验证
通过 curl 测试 HTTPS 是否正常工作:
curl -sI https://sub2api.your-domain.example.com | grep -i 'HTTP/'
应返回 HTTP/2 200。浏览器打开该地址,应能看到 Sub2API 的初始设置页面。
第八步:接入 NewAPI
Sub2API 部署完成后,在 NewAPI 管理后台的渠道页面添加自定义渠道:
- 类型:自定义渠道
- 名称:Sub2API
- Base URL:`https://sub2api.your-domain.example.com`(如在同一台 VPS 内部使用可直接写 `http://127.0.0.1:8081`)
- 密钥:在 Sub2API 管理后台生成的 API Key
这样 NewAPI 就可以将 Sub2API 作为上游渠道,把订阅配额分发给下游用户。
常见问题排查
| 错误 | 原因 | 解决方法 |
|---|---|---|
| 容器反复重启 | PostgreSQL/Redis 未就绪 | 检查 `depends_on` 中的 condition 是否配置正确 |
| 端口冲突(port is already allocated) | 宿主机端口已被占用 | 修改 `.env` 中的 `SERVER_PORT` 使用其他端口,或停掉占用端口的服务 |
| 502 Bad Gateway | nginx 代理端口与容器端口不一致 | 确认 `proxy_pass` 的端口号与 `SERVER_PORT` 一致 |
| 管理员无法登录 | JWT_SECRET 每次重启变化 | 设置固定的 `JWT_SECRET` 环境变量 |
| 粘性会话不生效 | Nginx 丢弃了 `session_id` 头 | 检查 nginx 配置中是否包含 `underscores_in_headers on;` |