主题
运维
部署与初始化完成后的日常:对外收敛(HTTPS、管理面白名单)、数据备份、版本升级、故障排查。本页的所有操作都以部署页的目录约定(/opt/ciyi-core/data)为基准。
1. 对外收敛(强烈建议上线前完成)
默认形态下引擎 6200 与控制台 8081 都是公网可达的裸 HTTP。生产使用前做两件事:
1.1 前置一层 nginx(TLS + 统一入口)
把两个端口收到一个域名后面,示例(仅列出关键 location):
nginx
server {
listen 443 ssl;
server_name relay.example.com; # API 网关域名(程序调用用)
# ssl_certificate ...; ssl_certificate_key ...;
# 转发端点:直透引擎(SSE 流式,关闭缓冲)
location / {
proxy_pass http://127.0.0.1:6200;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_buffering off;
proxy_read_timeout 3600s; # 长对话不被中间层掐断
}
}
server {
listen 443 ssl;
server_name console.example.com; # 控制台域名(浏览器用)
location /api/ {
proxy_pass http://127.0.0.1:8081; # 复用 ciyi-web 容器自带的反代与限速
}
location / {
proxy_pass http://127.0.0.1:8081;
}
}收敛后把引擎与控制台的 -p 端口映射改为只绑本机(-p 127.0.0.1:6200:6200),公网只暴露 443。
1.2 管理面白名单
/api/v1/admin/* 是全权接口(用户、渠道、凭证、价格),不应该暴露给公网任意来源。两种做法:
- 前置 nginx 里加源 IP 白名单:
nginx
location /api/v1/admin/ {
allow 203.0.113.10; # 你的办公/家庭出口 IP
allow 198.51.100.0/24; # 或整个网段
deny all;
proxy_pass http://127.0.0.1:8081;
}- 或干脆不给管理面任何公网入口,需要时 SSH 隧道进去:
ssh -L 8081:127.0.0.1:8081 user@server,浏览器开http://localhost:8081。
控制台镜像自带的 web/deploy/nginx.conf 已内置管理登录限速(/api/v1/admin/login 10 次/分钟 + burst 5),白名单是它的上一道闸,两层都要。
1.3 trust_proxy_headers
经过反代后,引擎看到的来源 IP 全是反代机地址——爆破锁、审计、限流都会失真。在 config.yaml 里开启:
yaml
trust_proxy_headers: true引擎改从 X-Forwarded-For / X-Real-IP 取真实来源(仅在「流量确实全部经过可信反代」时开启,直连暴露时开了反而可被伪造 IP 绕过爆破锁)。
2. 数据备份
引擎的全部状态 = 数据目录里的 SQLite 数据文件(+ WAL/SHM 伴生文件)+ 你脑子里的 CIYI_CREDENTIAL_KEY。
2.1 备份什么
| 对象 | 说明 |
|---|---|
/opt/ciyi-core/data/ 整目录 | 唯一需要备份的运行时状态。必须连 -wal 文件一起——WAL 里可能有尚未 checkpoint 的最新事务,只拷主文件会丢近期写入 |
CIYI_CREDENTIAL_KEY | 不在数据文件里!密钥丢失 = 渠道凭证与令牌密文全部无法解密(见部署页警告)。与数据分开存放 |
2.2 备份方式
最稳的做法是先停写、再快照(冷备,无一致性问题):
bash
docker stop ciyi-core
sudo tar -C /opt/ciyi-core -czf /backup/ciyi-$(date +%F).tar.gz data
docker start ciyi-core不停机热备时,用 sqlite3 在线备份代替直接拷文件(直接拷正在写的库有截断风险):
bash
sqlite3 /opt/ciyi-core/data/ciyi.db ".backup '/backup/ciyi-$(date +%F).db'"加进 cron(示例:每天 4:17 备份,保留 14 天):
text
17 4 * * * sqlite3 /opt/ciyi-core/data/ciyi.db ".backup '/backup/ciyi-$(date +\%F).db'" && find /backup -name 'ciyi-*.db' -mtime +14 -delete2.3 恢复
bash
docker stop ciyi-core
sudo rm -rf /opt/ciyi-core/data && sudo mkdir /opt/ciyi-core/data
sudo tar -C /opt/ciyi-core -xzf /backup/ciyi-2026-09-13.tar.gz
docker start ciyi-core # 用同一份 CIYI_CREDENTIAL_KEY 启动定期演练恢复
没恢复过的备份不算备份。建议每季度抽一份备份在临时容器里拉起验证(docker run --rm -v ... 挂备份目录起一个引擎,curl healthz + 登录一次)。
3. 升级
数据库迁移是单向的:新版本启动时自动执行增量迁移并记录进度,没有降级迁移。因此升级流程 = 备份 → 换镜像 → 起容器:
bash
# 1) 备份(必须!回滚全靠它)
docker stop ciyi-core
sudo tar -C /opt/ciyi-core -czf /backup/ciyi-pre-upgrade.tar.gz data
# 2) 换镜像
docker load -i ciyi-core-新版本.tar.gz # 或重新 build
# 3) 原地重建容器(沿用原命令:同数据卷、同 env)
docker rm ciyi-core
docker run -d --name ciyi-core ... ciyi-core:新版本
# 4) 验证
curl http://127.0.0.1:6200/healthz # ok
docker logs ciyi-core --tail 50 # 迁移日志无 error控制台 ciyi-web 无状态,随时可以换(先升 core 再升 web,避免 web 用到还没上线的接口)。
回滚:镜像可以直接退回旧版,但旧版引擎打不开已迁移的新库。若新版本迁移已执行且回滚不可避免,用升级前快照整体还原数据目录(这就是第 1 步必须冷备的原因)。
4. SQLite 单文件注意事项
- 不要把数据目录放 NFS / 网络盘:SQLite 的文件锁在网络文件系统上不可靠,会出现丢写或库损坏。本地 SSD 是正解。
- 磁盘写满 = 写请求报错:日志与流水只增不删,大流量部署定期关注磁盘水位;清理历史请走管理面的日志功能,不要直接删库里的行。
- 单机单写者:引擎独占该库文件,不要再让其他进程同时写它(只读挂载分析另说,也建议拿备份副本去分析)。
5. 日志与排障
5.1 看哪里的日志
bash
docker logs ciyi-core --tail 100 -f # 引擎运行日志(stderr,结构化)
docker logs ciyi-web --tail 50 # 反代访问/错误日志5.2 常见问题
引擎反复重启
docker logs 里找第一屏的 fatal:多半是 CIYI_CREDENTIAL_KEY 缺失/非法(fail-closed 拒启),或数据文件权限问题。
调用 5xx,日志里 upstream 错误
渠道上游侧问题:凭证过期、上游限流、模型未开通。渠道页跑一次「探活」定位;多条渠道同模型可互为兜底(自动重试其他渠道)。
控制台能开但登录 429
登录限速触发(连续失败多次)。等几分钟,或检查 trust_proxy_headers 配置是否与实际链路匹配(全内网代理 IP 被当成同一个来源累计计数)。
磁盘增长快
大头是请求日志。管理面「使用日志」支持按时间清理历史;清理前先按第 2 节做一次全量备份。
时区看着不对
引擎日志与页面时间跟随容器 UTC。需要本地时间观感时给容器加 -e TZ=Asia/Shanghai。
6. 安全清单(上线前过一遍)
- [ ] 引擎/控制台端口只绑
127.0.0.1,公网仅 443 - [ ] TLS 证书就位(HTTP 只做跳转)
- [ ]
/api/v1/admin/*有源 IP 白名单或不暴露公网 - [ ]
trust_proxy_headers与实际链路匹配 - [ ]
CIYI_CREDENTIAL_KEY存进密码管理器,且与备份分开存放 - [ ] 备份 cron 已跑通,恢复演练做过一次
- [ ] 管理员密码不是弱密码;不用的用户已停用