Skip to Content
欢迎来到左维WILL的技术博客与知识站
DocsAI 系统运维Sub2API 接入 CLIProxyAPI 小规模分发部署手册

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>:8443

DNS

在域名服务商添加 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,任何防火墙收口都必须只针对 180808443 或 Sub2API 相关端口,不要影响现有节点端口。

备份清单

至少备份:

/opt/sub2api-deploy/.env /opt/sub2api-deploy/docker-compose.yml /opt/sub2api-deploy/postgres_data /opt/sub2api-deploy/redis_data /etc/caddy/Caddyfile

CLIProxyAPI 所在住宅 VPS 另行备份:

/opt/cliproxyapi/config.yaml /opt/cliproxyapi/auth/

备份文件应加密保存,不要放入公开仓库。

回滚方式

如果 HTTPS 反代异常:

systemctl stop caddy

Sub2API 仍可通过:

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

Last updated on