====== 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:-admin@sub2api.local}
- 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=
TOTP_ENCRYPTION_KEY=
**关键说明**:
- **端口映射**:容器内部监听 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;` |
{{tag>Sub2API Docker 部署 nginx Cloudflare 反向代理}}