订阅转API:Windows + Docker 部署 Sub2,接入 Codex 与 Claude Code
订阅转API:Windows + Docker 部署 Sub2,接入 Codex 与 Claude Code
免责声明:本文仅记录本机技术验证过程,不构成对任何服务条款、账号安全或长期可用性的保证。请以项目最新文档和上游服务商最新规则为准。
本文中的“转 API”指通过第三方开源网关提供兼容接口,不是把 ChatGPT Plus 订阅兑换成 OpenAI 官方 API 额度。适用范围:本人合法持有的账号、本机自用、技术学习与兼容性测试。不要用于账号共享、转售、绕过限制或公开中转服务。
实测环境:Windows 11、Docker Desktop、Sub2
v0.1.169,验证日期2026-08-02。项目更新较快,界面名称可能略有变化。
很多人订阅了后,会自然地问两个问题:
- 能不能让 Codex、Claude Code 等本地编程工具使用这份订阅能力?
- 能不能在本机统一管理 OAuth、Key、模型映射和使用记录?
可以用 Sub2API 搭建一个只监听本机的兼容网关,但必须先讲清楚边界:ChatGPT 与 OpenAI API 是两个独立计费系统。OpenAI 帮助中心明确说明,API 服务与 ChatGPT 分开管理、分开计费。本文方案是第三方兼容层,不会给你的 OpenAI API 账户增加余额。
本文从零完成以下链路:
ChatGPT Plus / Codex OAuth | v Sub2API(127.0.0.1:18080) | | v v Codex CLI CC Switch / Claude Code | v PostgreSQL + Redis(仅 Docker 内网)你最终会得到:
- 一个只允许本机访问的 Sub2API 管理后台;
- 一个通过本人 OpenAI OAuth 导入的账号;
- 一把带额度上限的本机 API Key;
- Codex CLI 的 Responses API 兼容入口;
- Claude Code 的
/v1/messages兼容入口; - 可查询的使用记录、模型映射和订阅窗口用量。
一、开始前必须知道的 5 件事
1. ChatGPT Plus 不等于 OpenAI API 余额
不要把这篇文章理解成“官方订阅转官方 API”。如果你的程序需要稳定、合规的生产 API,应该直接在 OpenAI API 平台开通按量计费。
2. 第三方 OAuth 网关存在条款与封号风险
Sub2API 项目本身也提示了上游服务条款风险。是否允许某种接入方式,应以上游服务商的最新条款为准。本文不承诺账号安全,也不建议把主账号用于公开服务。
3. 本文只做本机部署
本文不配置域名,不开放公网,不做多用户分发。服务绑定到:
127.0.0.1:18080这意味着同一局域网的其他设备也不能直接访问。
4. OAuth 登录必须由账号本人完成
密码、验证码、OAuth 授权确认应由账号本人操作。不要把回调链接、Access Token、Refresh Token、Cookie 或完整 API Key 发给别人。
5. Claude Code 与 Codex 的客户端限制不同
如果账号开启“仅允许 Codex 官方客户端”,Codex 可以使用,但 Claude Code 会被拒绝。准备同时接入 Claude Code 时,需要关闭这个账号级限制,并在 OpenAI 分组中开启/v1/messages调度。
二、环境准备
硬件与软件
| 项目 | 建议 |
|---|---|
| 系统 | Windows 10/11 64 位 |
| 虚拟化 | WSL 2,可在 Docker Desktop 安装时启用 |
| Docker | Docker Desktop 最新稳定版 |
| 内存 | 至少 8 GB |
| 磁盘 | 至少预留 10 GB |
| 浏览器 | Edge、Chrome 或 Codex 内置浏览器 |
| 可选客户端 | Codex CLI、Claude Code、CC Switch |
先确认 Docker Desktop 已启动,然后打开 PowerShell:
docker version docker compose version两条命令都能正常返回版本信息,再继续。
检查端口是否占用
本文使用18080,避免和常见的8080服务冲突:
Get-NetTCPConnection-LocalPort 18080-ErrorAction SilentlyContinue没有输出通常表示端口可用。如果被占用,后文把SERVER_PORT改成其他未使用端口即可。
三、准备部署目录
创建单独目录:
New-Item-ItemType Directory-Path C:\sub2api-localSet-LocationC:\sub2api-local目录中至少需要两个文件:
C:\sub2api-local ├── .env └── compose.yaml1. 创建.env
先生成随机密钥。下面函数兼容 Windows PowerShell 5:
functionNew-HexSecret{$secretBytes=New-Objectbyte[]32[Security.Cryptography.RandomNumberGenerator]::Create().GetBytes($secretBytes)-join($secretBytes|ForEach-Object{$_.ToString('x2')})}New-HexSecret分别生成 PostgreSQL、Redis、JWT 和 TOTP 密钥。管理员密码建议由密码管理器单独生成,不要复用其他网站密码。
新建.env,填入以下内容并替换占位值:
COMPOSE_PROJECT_NAME=sub2api SUB2API_IMAGE=weishaw/sub2api:latest POSTGRES_IMAGE=postgres:18-alpine REDIS_IMAGE=redis:8-alpine BIND_HOST=127.0.0.1 SERVER_PORT=18080 RUN_MODE=standard TZ=Asia/Shanghai POSTGRES_USER=sub2api POSTGRES_PASSWORD=替换为随机64位十六进制字符串 POSTGRES_DB=sub2api REDIS_PASSWORD=替换为随机64位十六进制字符串 ADMIN_EMAIL=admin@sub2api.local ADMIN_PASSWORD=替换为强随机密码 JWT_SECRET=替换为随机64位十六进制字符串 JWT_EXPIRE_HOUR=12 TOTP_ENCRYPTION_KEY=替换为随机64位十六进制字符串 UPDATE_PROXY_URL=为什么这里先使用RUN_MODE=standard?因为标准模式能看到“分组管理”,后面需要开启 OpenAI 的/v1/messages。全部配置完成后,可以再切回simple。
2. 创建compose.yaml
name:sub2apiservices:sub2api:image:${SUB2API_IMAGE:-weishaw/sub2api:latest}restart:unless-stoppedsecurity_opt:-no-new-privileges:trueports:-"${BIND_HOST:-127.0.0.1}:${SERVER_PORT:-18080}:8080"volumes:-./data:/app/data:Zenvironment:AUTO_SETUP:"true"SERVER_HOST:0.0.0.0SERVER_PORT:8080SERVER_MODE:releaseRUN_MODE:${RUN_MODE:-standard}TZ:${TZ:-Asia/Shanghai}DATABASE_HOST:postgresDATABASE_PORT:5432DATABASE_USER:${POSTGRES_USER:-sub2api}DATABASE_PASSWORD:${POSTGRES_PASSWORD:?POSTGRES_PASSWORD is required}DATABASE_DBNAME:${POSTGRES_DB:-sub2api}DATABASE_SSLMODE:disableREDIS_HOST:redisREDIS_PORT:6379REDIS_PASSWORD:${REDIS_PASSWORD:?REDIS_PASSWORD is required}REDIS_DB:0ADMIN_EMAIL:${ADMIN_EMAIL:-admin@sub2api.local}ADMIN_PASSWORD:${ADMIN_PASSWORD:?ADMIN_PASSWORD is required}JWT_SECRET:${JWT_SECRET:?JWT_SECRET is required}JWT_EXPIRE_HOUR:${JWT_EXPIRE_HOUR:-12}TOTP_ENCRYPTION_KEY:${TOTP_ENCRYPTION_KEY:?TOTP_ENCRYPTION_KEY is required}SECURITY_TRUST_FORWARDED_IP_FOR_API_KEY_ACL:"false"SECURITY_FORWARDED_CLIENT_IP_HEADERS:""SECURITY_URL_ALLOWLIST_ENABLED:"true"SECURITY_URL_ALLOWLIST_ALLOW_INSECURE_HTTP:"false"SECURITY_URL_ALLOWLIST_ALLOW_PRIVATE_HOSTS:"false"UPDATE_PROXY_URL:${UPDATE_PROXY_URL:-}depends_on:postgres:condition:service_healthyredis:condition:service_healthynetworks:sub2api-network:ipv4_address:172.30.0.2healthcheck:test:["CMD","wget","-q","-T","5","-O","/dev/null","http://localhost:8080/health"]interval:30stimeout:10sretries:3start_period:45spostgres:image:${POSTGRES_IMAGE:-postgres:18-alpine}restart:unless-stoppedsecurity_opt:-no-new-privileges:truevolumes:-./postgres_data:/var/lib/postgresql/data:Zenvironment:POSTGRES_USER:${POSTGRES_USER:-sub2api}POSTGRES_PASSWORD:${POSTGRES_PASSWORD:?POSTGRES_PASSWORD is required}POSTGRES_DB:${POSTGRES_DB:-sub2api}PGDATA:/var/lib/postgresql/dataTZ:${TZ:-Asia/Shanghai}networks:sub2api-network:ipv4_address:172.30.0.3healthcheck:test:["CMD-SHELL","pg_isready -U ${POSTGRES_USER:-sub2api} -d ${POSTGRES_DB:-sub2api}"]interval:10stimeout:5sretries:5start_period:15sredis:image:${REDIS_IMAGE:-redis:8-alpine}restart:unless-stoppedsecurity_opt:-no-new-privileges:truevolumes:-./redis_data:/data:Zcommand:>sh -c ' redis-server --save 60 1 --appendonly yes --appendfsync everysec --requirepass "$$REDIS_PASSWORD"'environment:REDIS_PASSWORD:${REDIS_PASSWORD:?REDIS_PASSWORD is required}REDISCLI_AUTH:${REDIS_PASSWORD:?REDIS_PASSWORD is required}TZ:${TZ:-Asia/Shanghai}networks:sub2api-network:ipv4_address:172.30.0.4healthcheck:test:["CMD","redis-cli","ping"]interval:10stimeout:5sretries:5start_period:10snetworks:sub2api-network:driver:bridgeipam:config:-subnet:172.30.0.0/24这个配置有三个关键安全点:
- 只有 Sub2API 映射到宿主机,并且只绑定
127.0.0.1; - PostgreSQL 和 Redis 没有
ports,外部无法直接连接; - Redis 开启密码和 AOF 持久化。
四、启动 Sub2API
先校验 Compose:
docker compose config--quiet拉取镜像并启动:
docker compose pull docker compose up-d docker composeps第一次启动需要下载镜像并初始化数据库,耐心等待所有服务进入healthy。
健康检查:
Invoke-RestMethodhttp://127.0.0.1:18080/health预期结果:
{"status":"ok"}浏览器打开:
http://127.0.0.1:18080使用.env中的ADMIN_EMAIL和ADMIN_PASSWORD登录。
不要用
docker compose config、截图或日志把完整密钥发到公开平台,因为解析后的 Compose 配置可能包含真实密码。
五、完成后台初始化
第一次登录建议完成三件事:
- 阅读并确认项目合规提示;
- 修改管理员密码,启用 TOTP;
- 确认服务仍然只监听
127.0.0.1。
如果准备发教程截图,请遮住以下内容:
- OpenAI 邮箱;
- OAuth 回调 URL;
- Access Token 和 Refresh Token;
- 完整 API Key;
- 管理员邮箱、余额和机器公网 IP。
六、导入本人 ChatGPT Plus / Codex OAuth
进入:
账号管理 -> 添加账号 -> OpenAI -> OAuth建议设置:
| 配置项 | 推荐值 |
|---|---|
| 名称 | ChatGPT Plus - 本机 |
| 调度 | 开启 |
| 训练数据共享 | 关闭 |
| 仅允许 Codex 官方客户端 | 只使用 Codex 时开启;要接 Claude Code 时关闭 |
| 允许 Codex app-server 客户端 | 没有明确需求时关闭 |
随后点击 OAuth 授权,由账号本人完成 OpenAI 登录、验证码和授权确认。
导入成功后,账号页通常能看到:
- 平台:OpenAI;
- 类型:OAuth;
- 套餐:Plus;
- 状态:正常;
- 5 小时和 7 天用量窗口;
- OAuth 到期时间。
测试上游连接
在账号右侧选择:
更多 -> 测试连接测试模型选择当前账号实际支持的 Codex 模型。本文实测GPT-5.6 Sol成功返回响应。
如果默认模型返回:
The 'gpt-5.2' model is not supported when using Codex with a ChatGPT account.这不是 OAuth 失败,而是测试模型不兼容。改选账号实际支持的 Codex 模型后重试。
七、开启 Claude Code 的/v1/messages
这是最容易漏掉的一步,也是出现 403 的主要原因。
进入:
分组管理 -> openai-default -> 编辑确认平台为 OpenAI,然后开启:
允许 /v1/messages 调度为了让 Claude Code 的模型名统一落到GPT-5.6 Sol,把三类映射设置为:
| Claude 模型族 | 目标模型 |
|---|---|
| Opus | gpt-5.6-sol |
| Sonnet | gpt-5.6-sol |
| Haiku | gpt-5.6-sol |
保存后再创建 API Key。这样 Key 的鉴权快照会直接包含最新分组配置。
为什么不建议直接改数据库
Sub2API 会把 API Key 的鉴权快照缓存到 Redis。直接修改数据库虽然能看到字段变化,实际请求仍可能读取旧缓存。优先通过后台页面修改;如果已经创建了 Key,可在分组保存后重新编辑并保存一次 Key,或创建一把新 Key。
八、创建本机 API Key
进入:
API 密钥 -> 创建密钥推荐配置:
| 配置项 | 示例 |
|---|---|
| 名称 | claude-code-local |
| 分组 | openai-default |
| 额度限制 | $100,按个人需要调整 |
| IP 限制 | 本文依靠127.0.0.1绑定,不额外开启 |
| 有效期 | 自用可长期有效,也可设置定期轮换 |
创建后,完整 Key 只保存到密码管理器或 CC Switch,不要放进文章、Git 仓库、聊天记录和截图。
GitHub 提醒:把
.env、auth.json、真实 Key 和备份目录加入.gitignore,不要提交。
九、接入 Codex CLI
在 API 密钥页面点击“使用密钥”,选择:
Codex CLI -> Windows后台会生成当前版本对应的config.toml和auth.json。优先复制后台生成的配置,不要照搬过时文章。
Windows 默认目录:
%USERPROFILE%\.codex\config.toml %USERPROFILE%\.codex\auth.json核心配置应包含:
model_provider = "OpenAI" model = "gpt-5.6-sol" [model_providers.OpenAI] name = "OpenAI" base_url = "http://127.0.0.1:18080" wire_api = "responses" requires_openai_auth = true这里的base_url不要自行追加/v1;Sub2API 当前生成的 Codex 配置直接使用站点根地址。若新版后台给出的内容不同,以“使用密钥”页面当场生成的配置为准。
auth.json中保存后台生成的 API Key。不要把真实值提交到 Git。
启动 Codex 后发送一个最小请求,并到 Sub2API 的“使用记录”中确认:
- 请求状态成功;
- 请求模型是
gpt-5.6-sol; - 账号与 API Key 命中正确;
- 用量窗口有相应变化。
十、接入 CC Switch 与 Claude Code
1. 在 CC Switch 中添加自定义供应商
选择:
Claude Code -> 添加新供应商 -> 自定义配置填写:
| 字段 | 值 |
|---|---|
| 供应商名称 | Sub2API Local |
| API Key | 后台生成的claude-code-localKey |
| 请求地址 | http://127.0.0.1:18080 |
请求地址不要在末尾手动追加/v1/messages,Claude Code 会自动请求该路径。
配置 JSON 可保留 CC Switch 自动生成的认证字段,并把模型设置为:
{"env":{"CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC":1,"CLAUDE_MODEL":"claude-4-sonnet"},"permissions":{"allow":[],"deny":[]}}claude-4-sonnet会通过前面配置的分组映射转到gpt-5.6-sol。
保存供应商并点击“启用”。
2. 验证 Claude Code
打开新的 PowerShell:
claude-p"Reply with exactly: claude-cli-ok"--output-format text预期输出:
claude-cli-ok然后进入 Sub2API 的“使用记录”,确认模型映射链类似:
claude-4-sonnet -> gpt-5.6-sol这一步同时证明了四层链路都正常:
Claude Code -> CC Switch -> Sub2API /v1/messages -> OpenAI OAuth十一、可选:切回简易模式
配置完成后,如果只想保留精简后台,可把.env改为:
RUN_MODE=simple环境变量变化后不能只运行docker compose restart,需要重新创建容器:
docker compose up-d--force-recreate sub2api简易模式会隐藏部分管理页面,但已经保存的分组配置仍然有效。以后需要修改/v1/messages映射时,再临时切回standard。
十二、高频报错与解决办法
1.403 This group does not allow /v1/messages dispatch
原因:API Key 绑定的 OpenAI 分组没有开启 Claude Messages 兼容调度。
解决顺序:
- 切到
RUN_MODE=standard; - 编辑 Key 实际绑定的 OpenAI 分组;
- 开启“允许
/v1/messages调度”; - 保存模型映射;
- 重新编辑保存 API Key,或创建新 Key;
- 重启 Sub2API 后再测试。
2. Claude Code 显示Please run /login
如果后面同时出现 Sub2API 的 401/403,/login往往只是上游认证失败后的提示。使用自定义网关时,应先检查:
- CC Switch 是否启用了正确供应商;
- Base URL 是否为
http://127.0.0.1:18080; - API Key 是否正确;
- Key 是否绑定
openai-default; /v1/messages是否开启;- 账号是否关闭“仅允许 Codex 官方客户端”。
3.This account only allows Codex official clients
原因:账号启用了 Codex 官方客户端限制,而请求来自 Claude Code、curl 或其他客户端。
解决:编辑 OpenAI OAuth 账号,关闭“仅允许 Codex 官方客户端”。只使用 Codex 时可以保持开启。
4. 测试模型返回 400 不支持
原因:OAuth 有效,但选择了该 ChatGPT/Codex 账号不支持的模型。
解决:在“测试连接”中改选当前可用的 Codex 模型。本文实测GPT-5.6 Sol可用,但模型权限与名称会随版本和账号变化。
5. CC Switch 提示未安装或协议未注册
便携版 CC Switch 可能没有注册ccswitch://协议,因此 Sub2API 的“一键导入”会失败。
解决:在 CC Switch 内手动添加自定义供应商,不影响实际使用。
6.401 Unauthorized
依次检查:
- Key 是否复制完整;
- Key 是否处于启用状态;
- Base URL 是否指向正确端口;
- CC Switch 是否启用了刚创建的供应商;
- 是否误用了另一把绑定到 Anthropic 分组的 Key。
7.429 Too Many Requests
429 不一定来自本机限流,也可能来自订阅窗口或上游风控。查看账号页的 5 小时/7 天窗口、使用记录和容器日志:
docker compose logs--tail 200 sub2api不要通过增加账号、切换 IP 等方式绕过上游限制。
8. 修改.env后配置没有生效
docker compose restart不会重新读取 Compose 环境变量。使用:
docker compose up-d--force-recreate sub2api9.18080无法访问
检查:
docker composepsdocker compose logs--tail 200 sub2apiGet-NetTCPConnection-LocalPort 18080-ErrorAction SilentlyContinue如果宿主机端口被占用,修改.env的SERVER_PORT,然后重新创建容器。
十三、备份、更新与停止
备份前需要知道什么
数据库备份可能包含 OAuth 凭证和已签发的 API Key,因此备份文件应按密码文件管理,不要上传网盘公开链接或 GitHub。
至少备份:
.env compose.yaml data/ postgres_data/ redis_data/更稳妥的方式是额外执行 PostgreSQLpg_dump,并将备份存放在加密磁盘。
更新镜像
更新前先备份,然后执行:
docker compose pull docker compose up-d--remove-orphansdocker composepsInvoke-RestMethodhttp://127.0.0.1:18080/health暂停服务
docker compose stop恢复:
docker composestart不要随意执行docker compose down -v,-v会删除命名卷。也不要手动删除postgres_data、redis_data和.env。
十四、安全检查清单
发布或长期使用前逐项确认:
BIND_HOST=127.0.0.1- PostgreSQL 和 Redis 没有映射宿主机端口
.env使用强随机密码- 管理员账号已修改密码并启用 TOTP
- OpenAI 训练数据共享已按个人要求关闭
- API Key 设置了合理额度
- 完整 Key、邮箱、Token、回调链接没有出现在截图中
.env、auth.json、备份目录已加入.gitignore- 没有把服务用于共享、转售或公网中转
- 已阅读 Sub2API 与上游服务商的最新条款
推荐.gitignore:
.env *.local auth.json backups/ data/ postgres_data/ redis_data/十五、常见问题 FAQ
Q1:这是不是 OpenAI 官方支持的 Plus 转 API?
不是。ChatGPT Plus 与 OpenAI API 分开计费。本文是第三方开源网关的本机兼容方案。
Q2:为什么选择本机部署?
本机绑定127.0.0.1能显著缩小暴露面,也不需要域名、证书和云安全组。对于单人自用,这是更克制的方案。
Q3:能不能给朋友或团队共用?
本文不覆盖共享或转售。账号订阅、OAuth 凭证和客户端使用方式应遵守上游条款。
Q4:为什么 Claude Code 里写的是 Claude 模型,实际却跑 GPT?
Claude Code 使用 Anthropic Messages 协议和 Claude 风格模型名。Sub2API 在 OpenAI 分组中把模型名映射到目标 GPT 模型,再把响应转换回兼容格式。
Q5:只用 Codex,还需要开启/v1/messages吗?
不需要。Codex 使用 Responses API;/v1/messages主要用于 Claude Code 兼容入口。
Q6:换模型需要改哪里?
Codex 在config.toml中修改模型;Claude Code 建议在 Sub2API 的 OpenAI 分组中修改 Opus/Sonnet/Haiku 映射。修改后重新测试账号与客户端。
Q7:OAuth 快过期了怎么办?
在账号管理中使用“刷新令牌”或“重新授权”,并确认账号状态和用量窗口恢复正常。不要把刷新令牌复制给第三方。
总结
整个流程可以压缩为一条主线:
安装 Docker Desktop -> 本机启动 Sub2API + PostgreSQL + Redis -> 本人完成 OpenAI OAuth -> 测试 GPT-5.6 Sol -> OpenAI 分组开启 /v1/messages -> 创建受限 API Key -> 接入 Codex / CC Switch / Claude Code -> 检查使用记录和模型映射 -> 备份真正决定能否一次成功的,不是 Docker 命令,而是三个配置关系:
- 账号限制:Claude Code 场景不能开启“仅允许 Codex 官方客户端”;
- 分组能力:OpenAI 分组必须允许
/v1/messages; - Key 绑定:Claude Code 使用的 Key 必须绑定到这个 OpenAI 分组。
把这三点理顺,Please run /login、403 messages dispatch和模型不匹配问题基本都能定位。
参考资料
- Sub2API 项目:https://github.com/Wei-Shaw/sub2api
- OpenAI 帮助中心:ChatGPT 订阅与 API 分开计费:https://help.openai.com/en/articles/8156019
- Docker Desktop for Windows:https://docs.docker.com/desktop/setup/install/windows-install/
- 结构参考文章:https://zhuanlan.zhihu.com/p/2032101946493027471
免责声明:本文仅记录本机技术验证过程,不构成对任何服务条款、账号安全或长期可用性的保证。请以项目最新文档和上游服务商最新规则为准。
