Sub2API 接入 CLIProxyAPI 小规模分发部署手册
这篇文档记录一套小规模 API 分发方案:CLIProxyAPI 运行在干净住宅 IP VPS 上,负责 Claude OAuth 与上游转发;Sub2API 运行在另一台网关 VPS 上,负责分发 key、额度限制、用量查询与 HTTPS 入口。
本文只记录可复用流程,不记录真实 IP、账号邮箱、API key、管理密码、OAuth token 文件名等隐私数据。实际部署时请用自己的值替换占位符。
本文默认 CLIProxyAPI 已经部署完成,并且 Claude OAuth 已由账号持有人手动完成。不要让第三方工具或自动化流程操作 Claude 登录页。
这套方案适合不开放注册、只有管理员一个账号、给 3-4 个可信使用者分发 API key 的场景。隔离单位是 API key,不是站内用户。
核心架构
使用者 / Claude Code / OpenAI-compatible 客户端
↓
https://<DOMAIN>:8443/v1
↓
Caddy:HTTPS 证书与反代
↓
Sub2API:分发 key、额度限制、用量查询
↓
CLIProxyAPI:http://<RESIDENTIAL_VPS_IP>:8317/v1
↓
Claude OAuth 账号| 模块 | 部署位置 | 作用 |
|---|---|---|
| CLIProxyAPI | 干净住宅 IP VPS | 将 Claude OAuth 能力转换为 OpenAI-compatible API |
| Sub2API | 网关 VPS | 分发 API key、统计用量、限制 5 小时消费额度 |
| PostgreSQL | 网关 VPS Docker 容器 | 持久化 Sub2API 数据 |
| Redis | 网关 VPS Docker 容器 | 缓存与速率控制 |
| Caddy | 网关 VPS | 提供 https://<DOMAIN>:8443,反代到 Sub2API |
| DNS | 域名服务商 | 将 <DOMAIN> 解析到网关 VPS |
适用场景
- CLIProxyAPI 已经在住宅 IP VPS 上稳定运行
- 网关 VPS 上可以运行 Docker、PostgreSQL、Redis
- 不开放站点注册,只有管理员一个 Sub2API 用户
- 需要给少量使用者分别发 key
- 每个 key 需要单独设置 5 小时消费限额
- 需要一个免登录额度查询页面
- VPS 上可能已有 x-ui / xray,部署时不能影响现有
443服务
不适合本文的场景:
- 需要公开注册和大量用户自助购买
- 需要精确读取 Claude 官方订阅的真实 5 小时额度
- 需要把 Claude 登录流程自动化
- 网关 VPS 内存过小,无法稳定运行 Docker + PostgreSQL + Redis
隐私与占位符
本文统一使用以下占位符:
<GATEWAY_VPS_IP> Sub2API 所在网关 VPS IP
<RESIDENTIAL_VPS_IP> CLIProxyAPI 所在住宅 IP VPS
<DOMAIN> 绑定到网关 VPS 的域名,例如 api.example.com
<ADMIN_EMAIL> Sub2API 管理员邮箱
<ADMIN_PASSWORD> Sub2API 管理员密码
<CLI_PROXY_API_KEY> CLIProxyAPI 给 Sub2API 使用的上游 key
<SUB2API_USER_KEY> Sub2API 分发给使用者的 key不要把真实 <CLI_PROXY_API_KEY>、<ADMIN_PASSWORD>、Claude OAuth token、Sub2API .env 原文写入公开文档或截图。
最终访问地址
部署完成后,推荐只给使用者这两个地址:
API Base URL:
https://<DOMAIN>:8443/v1
额度查询:
https://<DOMAIN>:8443/key-usage管理后台地址:
https://<DOMAIN>:8443管理后台不要公开传播。
整体部署流程
第一阶段:确认 CLIProxyAPI 上游
确认住宅 IP VPS 上的 CLIProxyAPI 已经可用,并只允许网关 VPS 访问。
第二阶段:确认网关 VPS 环境
检查系统、内存、磁盘、端口、x-ui / xray 状态,避免影响现有服务。
第三阶段:安装 Docker 与 Sub2API
用 Docker Compose 部署 Sub2API、PostgreSQL、Redis。
第四阶段:初始化 Sub2API
登录后台,关闭开放注册,创建分组和上游账号。
第五阶段:创建分发 key 与额度限制
只用一个管理员用户,创建多个 API key,每个 key 单独限制 5 小时消费额度。
第六阶段:配置带端口 HTTPS
用 Caddy 监听 8443,反代到 Sub2API 的 18080。
第七阶段:验证与收口
验证 API、额度查询、资源占用、证书续期和备份。
第一阶段:确认 CLIProxyAPI 上游
在住宅 IP VPS 上确认 CLIProxyAPI 状态:
systemctl status cliproxyapi --no-pager
ss -lntp | grep ':8317'从网关 VPS 测试到 CLIProxyAPI:
curl -sS http://<RESIDENTIAL_VPS_IP>:8317/
curl -sS http://<RESIDENTIAL_VPS_IP>:8317/v1/models \
-H 'Authorization: Bearer <CLI_PROXY_API_KEY>'如果无 key 访问返回类似:
{"error":"Missing API key"}说明请求已经到达 CLIProxyAPI,只是未携带 key,这是预期结果。
来源限制
CLIProxyAPI 的 8317 不建议完全公网开放。住宅 IP VPS 上应只允许:
- 住宅 VPS 本机
- 网关 VPS IP
- 必要的管理来源
示例规则:
iptables -A INPUT -p tcp --dport 8317 -s <GATEWAY_VPS_IP> -j ACCEPT
iptables -A INPUT -p tcp --dport 8317 -s 127.0.0.1 -j ACCEPT
iptables -A INPUT -p tcp --dport 8317 -j DROP如果住宅 IP VPS 上有 x-ui / xray,不要清空整张防火墙表,不要重启 x-ui。只追加与 8317 相关的规则,并确认现有节点端口不受影响。
第二阶段:确认网关 VPS 环境
在网关 VPS 上做只读检查:
hostname
date -u
uptime
free -h
df -h /
ss -lntp | grep -E ':(80|443|8443|18080)\b' || true
systemctl --no-pager --plain status x-ui docker 2>/dev/null || true重点确认:
| 项目 | 期望 |
|---|---|
| 内存 | 至少 2G 更稳,小规模 1G 也要配置 swap |
| 磁盘 | Docker 镜像和数据库至少预留数 GB |
443 | 如果已被 x-ui / xray 占用,不要动 |
18080 | 预留给 Sub2API |
8443 | 预留给 HTTPS 反代 |
80 | 用于 Caddy 自动申请和续期证书 |
如果机器已有 x-ui / xray,部署 Sub2API 时只新增 Docker 与 Caddy,不修改 x-ui 配置。
第三阶段:部署 Sub2API
安装 Docker
Ubuntu 示例:
apt-get update
apt-get install -y ca-certificates curl gnupg
install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg \
| gpg --dearmor -o /etc/apt/keyrings/docker.gpg
chmod a+r /etc/apt/keyrings/docker.gpg
. /etc/os-release
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu ${VERSION_CODENAME} stable" \
> /etc/apt/sources.list.d/docker.list
apt-get update
apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
systemctl enable --now docker
docker version
docker compose version创建部署目录
mkdir -p /opt/sub2api-deploy
cd /opt/sub2api-deploy准备环境变量
.env 中至少要有:
ADMIN_EMAIL=<ADMIN_EMAIL>
ADMIN_PASSWORD=<ADMIN_PASSWORD>
JWT_SECRET=<RANDOM_SECRET>
ENCRYPTION_KEY=<RANDOM_SECRET>
SERVER_PORT=18080
RUN_MODE=standard推荐生成随机值:
openssl rand -hex 32
openssl rand -base64 24.env 是敏感文件,里面可能包含管理员密码、JWT secret、数据库密码。不要提交到 Git,也不要截图公开。
Docker Compose 示例
services:
sub2api:
image: weishaw/sub2api:latest
container_name: sub2api
restart: unless-stopped
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
ports:
- "18080:8080"
env_file:
- .env
environment:
DATABASE_URL: postgres://sub2api:${POSTGRES_PASSWORD}@postgres:5432/sub2api?sslmode=disable
REDIS_URL: redis://redis:6379
volumes:
- ./data:/app/data
mem_limit: 512m
memswap_limit: 768m
postgres:
image: postgres:18-alpine
container_name: sub2api-postgres
restart: unless-stopped
environment:
POSTGRES_USER: sub2api
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: sub2api
volumes:
- ./postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U sub2api"]
interval: 10s
timeout: 5s
retries: 5
mem_limit: 512m
memswap_limit: 768m
redis:
image: redis:8-alpine
container_name: sub2api-redis
restart: unless-stopped
volumes:
- ./redis_data:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5
mem_limit: 128m
memswap_limit: 256m启动:
docker compose up -d
docker compose ps
curl -sS http://127.0.0.1:18080/health期望返回:
{"status":"ok"}第四阶段:初始化 Sub2API
浏览器打开:
http://<GATEWAY_VPS_IP>:18080用 .env 中的管理员账号登录。
模式选择
如果只想 3-4 个 key 小规模使用,建议:
- 不开放注册
- 只保留管理员一个用户
- 使用普通分组,不使用专属分组
- 每个使用者一个 API key
- 每个 key 单独设置 5 小时限额
只有一个管理员用户时,分组不需要选“专属”。“专属分组”主要用于多用户系统中控制某个用户是否能看到这个分组。不开注册、只有一个用户时,用普通分组更简单。
第五阶段:配置上游与分发 key
创建分组
在后台创建一个分组,例如:
分组名称: claude
平台类型: OpenAI
专属分组: 否这里选择 OpenAI,是因为 Sub2API 调用 CLIProxyAPI 的 OpenAI-compatible /v1 接口。
添加上游账号
在账号或上游配置中添加:
平台: OpenAI
Base URL: http://<RESIDENTIAL_VPS_IP>:8317/v1
API Key: <CLI_PROXY_API_KEY>
绑定分组: claude保存后测试模型列表或最小对话。
创建分发 key
进入 API Key / 密钥管理,创建多个 key:
key-01 -> 使用者 A
key-02 -> 使用者 B
key-03 -> 使用者 C
key-04 -> 使用者 D每个 key 都绑定同一个 claude 分组,但额度独立。
设置 5 小时限额
Sub2API 的 5 小时限额是 key 级别的消费限制:
5小时限额: <USD_LIMIT>注意:
- 单位是 USD 消费额
0表示不限制- 它不是 Claude 官方订阅后台的真实 5 小时额度
- 是否准确取决于上游响应是否带 token usage,以及 Sub2API 模型价格是否配置正确
建议先用较小值测试,例如:
0.01
0.05
0.10确认 /key-usage 页面用量会变化后,再调整到正式额度。
第六阶段:配置 HTTPS
如果网关 VPS 的 443 已被 x-ui / xray 占用,不要让 Sub2API 抢 443。推荐使用带端口 HTTPS:
https://<DOMAIN>:8443DNS
在域名服务商添加 A 记录:
Host: api
Type: A
Value: <GATEWAY_VPS_IP>
TTL: 默认
代理/CDN: DNS only在网关 VPS 上确认:
getent ahostsv4 <DOMAIN>应返回 <GATEWAY_VPS_IP>。
安装 Caddy
apt-get update
apt-get install -y debian-keyring debian-archive-keyring apt-transport-https curl gnupg
install -d -m 0755 /etc/apt/keyrings
curl -1sLf https://dl.cloudsmith.io/public/caddy/stable/gpg.key \
| gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt \
> /etc/apt/sources.list.d/caddy-stable.list
apt-get update
apt-get install -y caddy
caddy version安装后确认端口:
ss -lntp | grep -E ':(80|443|8443|18080)\b' || true期望:
80 Caddy
443 xray / x-ui
8443 暂未配置或 Caddy
18080 Docker / Sub2API配置 Caddy
备份原配置:
cp -a /etc/caddy/Caddyfile /etc/caddy/Caddyfile.bak-$(date +%Y%m%d%H%M%S)写入最小配置:
{
http_port 80
https_port 8443
}
<DOMAIN>:8443 {
reverse_proxy 127.0.0.1:18080
}验证并加载:
caddy validate --config /etc/caddy/Caddyfile
systemctl reload caddy
journalctl -u caddy --no-pager -n 80日志中看到类似信息,表示证书已签发:
authorization finalized
certificate obtained successfully验证访问:
curl -sS -D - https://<DOMAIN>:8443/key-usage -o /tmp/key-usage.html
head -c 200 /tmp/key-usage.html第七阶段:客户端使用
Claude Code 或其他 OpenAI-compatible 客户端中使用:
Base URL: https://<DOMAIN>:8443/v1
API Key: <SUB2API_USER_KEY>额度查询页面:
https://<DOMAIN>:8443/key-usage使用者只需要输入自己的 <SUB2API_USER_KEY>,不需要登录管理后台。
计费与额度说明
Sub2API 的计费逻辑不是直接读取 Claude 官方订阅额度,而是基于:
- 上游 API 返回的 token usage
- Sub2API 中配置的模型价格
- key 的额度与 5h / 1d / 7d 限制
可以理解为:
本次消费 = 输入 token * 输入单价 + 输出 token * 输出单价如果上游不返回 usage,或模型价格没有配置正确,额度统计就可能不准确。
因此,正式分发前必须做一次低额度验证:
curl https://<DOMAIN>:8443/v1/chat/completions \
-H 'Authorization: Bearer <SUB2API_USER_KEY>' \
-H 'Content-Type: application/json' \
-d '{
"model": "<MODEL_NAME>",
"messages": [{"role": "user", "content": "ping"}]
}'然后打开:
https://<DOMAIN>:8443/key-usage确认该 key 的用量发生变化。
资源监控
部署后建议观察 24-48 小时:
uptime
free -h
df -h /
docker stats --no-stream
docker compose -f /opt/sub2api-deploy/docker-compose.yml ps
journalctl -u caddy --no-pager -n 80
dmesg -T | grep -iE 'oom|killed process|out of memory' || true小规模使用时,常见资源占用应比较低:
sub2api 数十 MB 到数百 MB
sub2api-postgres 数十 MB 到数百 MB
sub2api-redis 数 MB 到数十 MB
caddy 数 MB 到数十 MB如果内存经常接近上限,应减少并发、调低容器内存限制风险,或迁移到更大 VPS。
安全收口
初期为了验证方便,Sub2API 可能同时暴露:
http://<GATEWAY_VPS_IP>:18080
https://<DOMAIN>:8443稳定后建议收口:
- 使用者只使用
https://<DOMAIN>:8443/v1 - 额度查询只使用
https://<DOMAIN>:8443/key-usage - 管理后台只自己访问
- 不公开裸 IP 与
18080 - 后续可用防火墙限制
18080只允许本机或管理来源访问
如果要把 18080 收到本机,Docker Compose 可改为:
ports:
- "127.0.0.1:18080:8080"修改后需要重建 Sub2API 容器:
docker compose up -d如果网关 VPS 上还有 x-ui / xray,任何防火墙收口都必须只针对 18080、8443 或 Sub2API 相关端口,不要影响现有节点端口。
备份清单
至少备份:
/opt/sub2api-deploy/.env
/opt/sub2api-deploy/docker-compose.yml
/opt/sub2api-deploy/postgres_data
/opt/sub2api-deploy/redis_data
/etc/caddy/CaddyfileCLIProxyAPI 所在住宅 VPS 另行备份:
/opt/cliproxyapi/config.yaml
/opt/cliproxyapi/auth/备份文件应加密保存,不要放入公开仓库。
回滚方式
如果 HTTPS 反代异常:
systemctl stop caddySub2API 仍可通过:
http://<GATEWAY_VPS_IP>:18080访问。
如果 Sub2API 异常:
cd /opt/sub2api-deploy
docker compose ps
docker compose logs --tail=100 sub2api
docker compose restart sub2api如果需要停止整套 Sub2API:
cd /opt/sub2api-deploy
docker compose down这不会影响住宅 VPS 上的 CLIProxyAPI,也不会影响网关 VPS 上的 x-ui,前提是没有修改它们的配置。
验收清单
- CLIProxyAPI 上游可从网关 VPS 访问
- CLIProxyAPI
8317已限制来源 - Sub2API、PostgreSQL、Redis 容器 healthy
- 管理员可以登录 Sub2API 后台
- 站点注册已关闭
- 已创建普通分组,例如
claude - 上游账号已绑定 CLIProxyAPI
/v1 - 已创建 3-4 个分发 key
- 每个 key 已设置 5 小时消费限额
-
/key-usage可以免登录查询 -
https://<DOMAIN>:8443证书正常 -
443仍由原 x-ui / xray 服务占用 - Claude Code 可以通过 Sub2API key 正常调用
-
.env、数据库、Caddyfile、CLIProxyAPI auth 已备份
常见问题
为什么不用专属分组?
如果站点不开放注册,只有管理员一个用户,分发对象只是拿不同 API key 使用服务,那么普通分组即可。专属分组适合多用户系统中控制某个用户是否能看到某个分组。
/key-usage 是公开页面安全吗?
它是免登录查询页面,但仍需要输入具体 API key 才能看到该 key 的用量。公开它本身会暴露服务存在,适合小范围使用。更高安全要求下,可以再加反代鉴权或访问来源限制。
5 小时限额等于 Claude 官方 5 小时额度吗?
不等于。Sub2API 的 5 小时限额是按 token usage 和模型价格计算的消费窗口,用来近似控制成本或用量。Claude 官方订阅的 5 小时额度由 Claude 官方系统决定,Sub2API 不能直接读取。
为什么 HTTPS 用 8443,不用标准 443?
因为很多节点 VPS 的 443 已经被 x-ui / xray 占用。为了不影响现有服务,Caddy 只监听 8443,同时用 80 申请和续期证书。
为什么还需要 Caddy 反代?
Sub2API 容器本身运行在 HTTP 18080。Caddy 负责 HTTPS 证书、TLS 加密和请求转发:
https://<DOMAIN>:8443 -> Caddy -> http://127.0.0.1:18080这样 Sub2API 不需要直接管理证书,也不需要抢占 443。