docs: record infra deployment and Gitea mirror setup

Capture the current new-api and Gitea remote deployment state so future maintenance uses the real runtime topology instead of stale assumptions.
This commit is contained in:
zizi 2026-04-05 20:15:15 +08:00
parent 677d02f2ab
commit dd0b85213b
3 changed files with 431 additions and 0 deletions

8
.mcp.json Normal file
View File

@ -0,0 +1,8 @@
{
"mcpServers": {
"tabby": {
"type": "http",
"url": "http://localhost:3001/mcp"
}
}
}

261
AGENTS.md
View File

@ -130,3 +130,264 @@ For request structs that are parsed from client JSON and then re-marshaled to up
- field absent in client JSON => `nil` => omitted on marshal;
- field explicitly set to zero/false => non-`nil` pointer => must still be sent upstream.
- Avoid using non-pointer scalars with `omitempty` for optional request parameters, because zero values (`0`, `0.0`, `false`) will be silently dropped during marshal.
# new-api 项目排障记录
## 本次对话确认的关键信息
### 1. 部署与配置位置
- 远程服务器:`个人-minione-ubuntu-infra-4c16g120g`
- `new-api` 以 Docker 容器运行,容器名:`new-api`
- 渠道配置不在 `docker-compose.yml` 里维护,核心数据在 PostgreSQL 数据库表中:
- `channels`
- `abilities`
- `options`
### 2. 新渠道 `xianyu-claude-opus4.6-40`
- 数据库中已存在该渠道,不是“未创建”问题。
- 关键字段:
- `name = xianyu-claude-opus4.6-40`
- `type = 14`
- `base_url = http://cccai.cfd`
- `models = claude-opus-4-6`
- `abilities` 已同步出三组能力:
- `default`
- `vip`
- `svip`
- 已补齐:
- `test_model = claude-opus-4-6`
### 3. 上游协议与验证方式
- 该渠道支持 `v1/messages`
- 直接请求上游验证通过:
- `POST http://cccai.cfd/v1/messages`
- Header 需要:
- `content-type: application/json`
- `x-api-key: <key>`
- `anthropic-version: 2023-06-01`
- 实测返回 `200`,模型 `claude-opus-4-6` 可正常响应。
### 4. `/api/channel/test` 报错的真实原因
- 报错:
- `模型 claude-opus-4-6 倍率或价格未配置`
- 这不是渠道连通性问题,而是计费配置问题。
- 代码位置:
- `relay/helper/price.go`
- 测试渠道时,服务端会先查:
- `options.ModelPrice`
- 查不到再查 `options.ModelRatio`
- 两者都 miss 时,就会抛出上面的错误。
### 5. 本次实际修复
- 远程数据库中的 `options.ModelRatio` 被自定义值覆盖,缺少:
- `claude-opus-4-6`
- 已补上:
- `ModelRatio["claude-opus-4-6"] = 2.5`
- 补完后验证通过:
- `GET /api/channel/test/9?model=claude-opus-4-6&endpoint_type=anthropic`
- 返回:`{"message":"","success":true,"time":8.601}`
### 6. 默认值与线上值的关系
- 代码默认倍率里本来就有:
- `claude-opus-4-6: 2.5`
- 代码位置:
- `setting/ratio_setting/model_ratio.go`
- 但线上运行时会被数据库中的 `options.ModelRatio` 覆盖。
- 结论:
- 代码里有默认值,不代表线上一定可用。
- 查问题时必须先看数据库 `options` 实际内容。
### 7. 线上热同步行为
- `new-api` 会定时从数据库同步 `options``channels`,不需要每次都重启容器。
- 日志关键字:
- `syncing options from database`
- `syncing channels from database`
- 这次补 `ModelRatio` 后,服务在热同步后即生效。
### 8. 当前遗留问题
- 日志里仍有报错:
- `failed to update option map: json: cannot unmarshal object into Go value of type float64`
- 说明某些 `options` JSON 结构与当前解析逻辑不匹配。
- 这次 `claude-opus-4-6` 问题已修复,但后续应专项清理 `ModelPrice` / 其他 option 的 JSON 格式问题。
## 后续排障原则
- 不要先改 Docker 配置,先查数据库表:
- `channels`
- `abilities`
- `options`
- 不要因为代码默认值存在,就假定线上有效。
- 遇到“倍率或价格未配置”时,优先检查:
- `options.ModelRatio`
- `options.ModelPrice`
- 遇到渠道测试失败时,先分清:
- 是上游不通
- 还是服务端计费配置缺失
## 9. 当前线上部署形态2026-04-04 更新)
- 远程服务器仍是:`个人-minione-ubuntu-infra-4c16g120g`
- `new-api` **不再**以 Docker 应用容器运行;当前由宿主机 `systemd` 服务启动:
- 服务名:`new-api`
- `systemctl is-active new-api` 应返回 `active`
- `systemctl is-enabled new-api` 应返回 `enabled`
- 当前线上运行版本固定为最新稳定 tag
- `v0.11.9`
- 实际部署目录不是 `/root/new-api`,而是单独的源码 worktree
- `/root/new-api-v0.11.9`
- 关键文件:
- 二进制:`/root/new-api-v0.11.9/new-api`
- 运行环境:`/root/new-api-v0.11.9/.env.runtime`
- 启动脚本:`/root/new-api-v0.11.9/run-new-api.sh`
- systemd 单元文件:`/etc/systemd/system/new-api.service`
## 10. 依赖服务与连接方式2026-04-04 更新)
- PostgreSQL 和 Redis 仍然跑在 Docker 中,但**只作为依赖容器**存在,不再承载应用本体。
- 当前容器:
- PostgreSQL`postgres`
- Redis`redis`
- 当前宿主机固定入口:
- PostgreSQL`127.0.0.1:5433`
- Redis`127.0.0.1:6379`
- `new-api` 宿主机进程必须连接宿主机固定入口,不要再依赖容器名或容器 IP
- `SQL_DSN=postgresql://root:123456@127.0.0.1:5433/new-api`
- `REDIS_CONN_STRING=redis://127.0.0.1:6379`
- 原因:
- 容器 IP 会变,写死就是垃圾设计。
- 用宿主机固定入口,重建 PG/Redis 容器时不需要改应用配置。
## 11. 数据保护与备份2026-04-04 更新)
- PostgreSQL 数据仍保存在 Docker volume
- `new-api_pg_data`
- **不要**删除、重建、覆盖这个 volume除非明确知道自己在做什么。
- 本次切换前已做 PG 备份:
- `/root/backups/new-api/new-api-cutover-20260404-094849.dump`
- 这次切换后已核对关键表仍在:
- `channels=10`
- `abilities=153`
- `options=9`
## 12. 运维入口与排障顺序2026-04-04 更新)
- 现在排障先看 `systemd`,不是先看 Docker 应用容器:
- `systemctl status new-api`
- `journalctl -u new-api -n 200 --no-pager`
- `journalctl -u new-api -f`
- 服务健康检查:
- `curl http://127.0.0.1:3000/api/status`
- 当前线上版本应看到:
- `v0.11.9`
- Docker 现在只需要关心依赖容器是否活着:
- `docker ps | grep -E 'postgres|redis'`
- 不要再默认使用 `/root/new-api/docker-compose.yml` 管理应用本体。
- 这个仓库目录现在主要是源码主仓库,不是实际运行目录。
- 实际运行目录是 `/root/new-api-v0.11.9`
## 13. 后续升级原则2026-04-04 更新)
- 升级时优先选择新的**稳定 tag**,不要直接拿 `main``latest` 当生产版本。
- 合理流程应该是:
1. 为目标稳定 tag 建单独部署目录或 worktree
2. 编译产出新二进制
3. 保留 PG volume不迁移数据库文件路径
4. 让 systemd 指向新版本
5. 验证 `api/status`、日志、数据库连接再收尾
- 如果有人再次看到 `docker-compose.yml` 里定义了 `new-api` 服务,不要想当然地认定线上还在用容器跑应用;先查:
- `systemctl status new-api`
- `ss -lntp | grep :3000`
## 14. infra 虚拟机上的 Gitea 部署2026-04-04 更新)
- 远程服务器:`个人-minione-ubuntu-infra-4c16g120g`
- Gitea 当前以 Docker 方式部署,不与 `new-api` 共用应用容器。
- 当前镜像固定为稳定版本:
- `docker.gitea.com/gitea:1.25.5`
- 容器名:
- `gitea`
- 访问端口:
- Web`3001`
- SSH`2222`
- 当前 Web 根地址配置为:
- `http://100.64.0.11:3001/`
- 如果后续公网域名或访问地址变了,优先修改:
- `/opt/gitea/data/gitea/conf/app.ini`
- 重点字段:`DOMAIN``SSH_DOMAIN``ROOT_URL`
## 15. Gitea 数据与配置位置2026-04-04 更新)
- Gitea 部署目录:
- `/opt/gitea`
- compose 文件:
- `/opt/gitea/docker-compose.yml`
- Gitea 数据目录bind mount不是 named volume
- `/opt/gitea/data`
- 主配置文件:
- `/opt/gitea/data/gitea/conf/app.ini`
- 敏感环境变量文件root only
- `/opt/gitea/.env`
- 这份 `.env` 里包含:
- PostgreSQL 密码
- Gitea 管理员初始密码
- Gitea 各类 secret/jwt token
- 不要把 `/opt/gitea/.env` 提交到仓库、复制到公开位置或随手改权限。
## 16. Gitea 与 PostgreSQL 的关系2026-04-04 更新)
- Gitea **复用了现有 PostgreSQL 实例**,但没有复用 `new-api` 的数据库。
- Gitea 专用 PostgreSQL 角色与数据库:
- role`gitea`
- database`gitea`
- 连接方式不是宿主机 `127.0.0.1:5433`,而是容器内直接走共享 Docker 网络:
- host`postgres:5432`
- 共享网络:
- `new-api_new-api-network`
- 原则:
- 复用的是 PG 实例,不是 `new-api` 数据库。
- 不要把 Gitea 表写进 `new-api` 库,那是纯粹找死。
## 17. Gitea 运维与排障2026-04-04 更新)
- 查看状态:
- `cd /opt/gitea && docker compose ps`
- `docker ps | grep gitea`
- 查看日志:
- `docker logs -f gitea`
- 重启:
- `cd /opt/gitea && docker compose restart`
- 健康检查:
- `curl --noproxy '*' http://127.0.0.1:3001/`
- 由于远程机器设置了代理环境变量,使用本机 `curl` 打本机端口时优先加:
- `--noproxy '*'`
- 否则很容易出现假的 `502`,把问题看错。
- Gitea SSH 应走**内置 SSH 服务**,当前正确的宿主机端口映射是:
- `2222:2222`
- 不要把宿主机 `2222` 映射到容器 `22`
- 那样连到的是容器里的 OpenSSH不是 Gitea SSH用户公钥会“看起来加了但就是登不上”。
## 18. Gitea 初始化状态2026-04-04 更新)
- 当前已完成初始化,不是安装向导状态。
- 首页应能看到:
- `Explore`
- `Sign In`
- 当前已创建管理员账号:
- 用户名:`admin`
- 初始密码不写进文档正文,去看:
- `/opt/gitea/.env`
- 第一次登录后应尽快修改管理员密码。
- 当前推荐通过 Tailscale 地址访问:
- Web`http://100.64.0.11:3001/`
- SSH`ssh -p 2222 git@100.64.0.11`
- 当前设备的 SSH 公钥已加入 `admin` 账号key title 为:
- `qingse-macbook-id_ed25519`
- 如果后续再次修改了 `2222` 的目标服务,客户端可能需要刷新:
- `~/.ssh/known_hosts`
## 19. Gitea 上的 new-api 镜像仓库2026-04-04 更新)
- 已在 Gitea 中创建仓库:
- `admin/new-api`
- 当前不是普通仓库,而是 **GitHub pull mirror**
- 上游:`https://github.com/QuantumNous/new-api.git`
- Gitea 地址:`http://100.64.0.11:3001/admin/new-api`
- SSH clone`ssh://git@100.64.0.11:2222/admin/new-api.git`
- 当前镜像同步间隔:
- `24h0m0s`
- 这类 mirror 的核心用途是同步 Git 数据:
- branches
- tags
- commits
- 不要把它误解成 GitHub 全量镜像站。
- 现在配置的不是 GitHub issue / PR / release 的持续双向同步。
- 它的重点是把仓库代码历史持续拉到 Gitea。

162
CLAUDE.md
View File

@ -130,3 +130,165 @@ For request structs that are parsed from client JSON and then re-marshaled to up
- field absent in client JSON => `nil` => omitted on marshal;
- field explicitly set to zero/false => non-`nil` pointer => must still be sent upstream.
- Avoid using non-pointer scalars with `omitempty` for optional request parameters, because zero values (`0`, `0.0`, `false`) will be silently dropped during marshal.
# new-api 项目排障记录
## 本次对话确认的关键信息
### 1. 部署与配置位置
- 远程服务器:`个人-minione-ubuntu-infra-4c16g120g`
- `new-api` 以 Docker 容器运行,容器名:`new-api`
- 渠道配置不在 `docker-compose.yml` 里维护,核心数据在 PostgreSQL 数据库表中:
- `channels`
- `abilities`
- `options`
### 2. 新渠道 `xianyu-claude-opus4.6-40`
- 数据库中已存在该渠道,不是“未创建”问题。
- 关键字段:
- `name = xianyu-claude-opus4.6-40`
- `type = 14`
- `base_url = http://cccai.cfd`
- `models = claude-opus-4-6`
- `abilities` 已同步出三组能力:
- `default`
- `vip`
- `svip`
- 已补齐:
- `test_model = claude-opus-4-6`
### 3. 上游协议与验证方式
- 该渠道支持 `v1/messages`
- 直接请求上游验证通过:
- `POST http://cccai.cfd/v1/messages`
- Header 需要:
- `content-type: application/json`
- `x-api-key: <key>`
- `anthropic-version: 2023-06-01`
- 实测返回 `200`,模型 `claude-opus-4-6` 可正常响应。
### 4. `/api/channel/test` 报错的真实原因
- 报错:
- `模型 claude-opus-4-6 倍率或价格未配置`
- 这不是渠道连通性问题,而是计费配置问题。
- 代码位置:
- `relay/helper/price.go`
- 测试渠道时,服务端会先查:
- `options.ModelPrice`
- 查不到再查 `options.ModelRatio`
- 两者都 miss 时,就会抛出上面的错误。
### 5. 本次实际修复
- 远程数据库中的 `options.ModelRatio` 被自定义值覆盖,缺少:
- `claude-opus-4-6`
- 已补上:
- `ModelRatio["claude-opus-4-6"] = 2.5`
- 补完后验证通过:
- `GET /api/channel/test/9?model=claude-opus-4-6&endpoint_type=anthropic`
- 返回:`{"message":"","success":true,"time":8.601}`
### 6. 默认值与线上值的关系
- 代码默认倍率里本来就有:
- `claude-opus-4-6: 2.5`
- 代码位置:
- `setting/ratio_setting/model_ratio.go`
- 但线上运行时会被数据库中的 `options.ModelRatio` 覆盖。
- 结论:
- 代码里有默认值,不代表线上一定可用。
- 查问题时必须先看数据库 `options` 实际内容。
### 7. 线上热同步行为
- `new-api` 会定时从数据库同步 `options``channels`,不需要每次都重启容器。
- 日志关键字:
- `syncing options from database`
- `syncing channels from database`
- 这次补 `ModelRatio` 后,服务在热同步后即生效。
### 8. 当前遗留问题
- 日志里仍有报错:
- `failed to update option map: json: cannot unmarshal object into Go value of type float64`
- 说明某些 `options` JSON 结构与当前解析逻辑不匹配。
- 这次 `claude-opus-4-6` 问题已修复,但后续应专项清理 `ModelPrice` / 其他 option 的 JSON 格式问题。
## 后续排障原则
- 不要先改 Docker 配置,先查数据库表:
- `channels`
- `abilities`
- `options`
- 不要因为代码默认值存在,就假定线上有效。
- 遇到“倍率或价格未配置”时,优先检查:
- `options.ModelRatio`
- `options.ModelPrice`
- 遇到渠道测试失败时,先分清:
- 是上游不通
- 还是服务端计费配置缺失
## 9. 当前线上部署形态2026-04-04 更新)
- 远程服务器仍是:`个人-minione-ubuntu-infra-4c16g120g`
- `new-api` **不再**以 Docker 应用容器运行;当前由宿主机 `systemd` 服务启动:
- 服务名:`new-api`
- `systemctl is-active new-api` 应返回 `active`
- `systemctl is-enabled new-api` 应返回 `enabled`
- 当前线上运行版本固定为最新稳定 tag
- `v0.11.9`
- 实际部署目录不是 `/root/new-api`,而是单独的源码 worktree
- `/root/new-api-v0.11.9`
- 关键文件:
- 二进制:`/root/new-api-v0.11.9/new-api`
- 运行环境:`/root/new-api-v0.11.9/.env.runtime`
- 启动脚本:`/root/new-api-v0.11.9/run-new-api.sh`
- systemd 单元文件:`/etc/systemd/system/new-api.service`
## 10. 依赖服务与连接方式2026-04-04 更新)
- PostgreSQL 和 Redis 仍然跑在 Docker 中,但**只作为依赖容器**存在,不再承载应用本体。
- 当前容器:
- PostgreSQL`postgres`
- Redis`redis`
- 当前宿主机固定入口:
- PostgreSQL`127.0.0.1:5433`
- Redis`127.0.0.1:6379`
- `new-api` 宿主机进程必须连接宿主机固定入口,不要再依赖容器名或容器 IP
- `SQL_DSN=postgresql://root:123456@127.0.0.1:5433/new-api`
- `REDIS_CONN_STRING=redis://127.0.0.1:6379`
- 原因:
- 容器 IP 会变,写死就是垃圾设计。
- 用宿主机固定入口,重建 PG/Redis 容器时不需要改应用配置。
## 11. 数据保护与备份2026-04-04 更新)
- PostgreSQL 数据仍保存在 Docker volume
- `new-api_pg_data`
- **不要**删除、重建、覆盖这个 volume除非明确知道自己在做什么。
- 本次切换前已做 PG 备份:
- `/root/backups/new-api/new-api-cutover-20260404-094849.dump`
- 这次切换后已核对关键表仍在:
- `channels=10`
- `abilities=153`
- `options=9`
## 12. 运维入口与排障顺序2026-04-04 更新)
- 现在排障先看 `systemd`,不是先看 Docker 应用容器:
- `systemctl status new-api`
- `journalctl -u new-api -n 200 --no-pager`
- `journalctl -u new-api -f`
- 服务健康检查:
- `curl http://127.0.0.1:3000/api/status`
- 当前线上版本应看到:
- `v0.11.9`
- Docker 现在只需要关心依赖容器是否活着:
- `docker ps | grep -E 'postgres|redis'`
- 不要再默认使用 `/root/new-api/docker-compose.yml` 管理应用本体。
- 这个仓库目录现在主要是源码主仓库,不是实际运行目录。
- 实际运行目录是 `/root/new-api-v0.11.9`
## 13. 后续升级原则2026-04-04 更新)
- 升级时优先选择新的**稳定 tag**,不要直接拿 `main``latest` 当生产版本。
- 合理流程应该是:
1. 为目标稳定 tag 建单独部署目录或 worktree
2. 编译产出新二进制
3. 保留 PG volume不迁移数据库文件路径
4. 让 systemd 指向新版本
5. 验证 `api/status`、日志、数据库连接再收尾
- 如果有人再次看到 `docker-compose.yml` 里定义了 `new-api` 服务,不要想当然地认定线上还在用容器跑应用;先查:
- `systemctl status new-api`
- `ss -lntp | grep :3000`