- 新增 5/20 下午工作日志:CI/CD 8个问题排查修复全过程 - 记录 Gitea 1.22.6 两个 bug 及解决方案 - 阶段四 CI/CD 标记完成,Gitea 升级到 1.23.8 - 更新待办速查 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
9.8 KiB
工作日志 — 2026-05-20
上午:状态检查
8核32G 蜂驰云 (120.53.227.155) 检查结果
| 项目 | 状态 | 说明 |
|---|---|---|
| Docker (mysql/redis/qdrant) | ✅ | 正常运行 |
| NestJS API (zhixi-api) | ✅ | systemd active |
| gitea-runner | ✅ | systemd active |
| Nginx + HTTPS | ✅ | api.longde.cloud |
| rag-worker 代码部署 | ✅ | /opt/zhixi/backend/rag-worker/ |
| rag-worker .env | ✅ | 所有密钥/endpoint 已配置 |
| Python 依赖 | ❌→✅ | 缺→28+ packages 全装 |
| Python 版本 | ✅ | 3.11.15(systemd 显式指定 /usr/bin/python3.11) |
| zhixi-worker systemd | ❌→✅ | enabled active,polling 正常 |
4核4G 轻量云 (81.70.187.179) 检查结果
全部正常,无变化。
今日完成
1. Python Worker 补全部署 ✅
- 修正 requirements.txt(补 qdrant-client + python-dotenv)
- config.py 添加 python-dotenv 加载兜底
- pip3.11 安装全部依赖(28+ packages)
- 创建 systemd zhixi-worker.service(PYTHONUNBUFFERED=1 + -u flag)
- 启动验证:enabled active
2. 百度 OCR 开通 + 凭据存储 ✅
- AppID: 7767914, API Key / Secret Key 存入
蜂驰云服务器凭据.md
3. 两服务器内网互联验证 ✅
- 4核4G (10.2.0.7) ↔ 8核32G (172.21.0.4),双向 ~1.9ms
- 8核32G Runner 从公网切换为内网
http://10.2.0.7:3000 - 凭据文件、部署方案文档均已更新
4. COS Bucket 验证 + 凭据补全 ✅
- Bucket
zhixi-1259685406确认存在(Server: tencent-cos) - SecretId/Key 从本地 .env 同步到服务器
/opt/zhixi/env/.env.production - cos-nodejs-sdk-v5 headBucket 验证通过
- 同区 VPC 内网访问,免流量费
5. 知识库设计文档全面更新 ✅
- 所有 25 节 + 32 项决策的状态标记更新
- 依赖项清单全部对齐实际部署状态(llama-index/tencentcloud-sdk 标注替代方案并打勾)
- 新增 6.5 两服务器内网互联章节
- COS 同区内网访问标注
6. 端到端导入全链路验证 ✅
- 创建测试数据(User/KnowledgeBase/KnowledgeSource/DocumentImport)
- Worker 完整执行:轮询→认领→解析→切片→embedding→Qdrant→候选知识点→完成
- 结果:DocumentImport COMPLETED 100%,1 chunk,4 candidates,Qdrant 6 points
修复 6 个 bug:
| 文件 | 问题 | 修复 |
|---|---|---|
| api_client.py | get_next_job 未解包 data.job |
加 result.get("job") |
| api_client.py | claim_job 缺 JSON body → NestJS 500 |
加 json={"workerId": WORKER_ID} |
| api_client.py | get_job_detail 未解包 data 层 |
data.get("data") or data |
| import_pipeline.py | 文件不存在时抛异常跳过 rawText 回退 | os.path.exists() 预检查 |
| import_pipeline.py | Qdrant point ID 须 UUID | str(uuid.uuid4()) |
| candidate_generator.py | .format() 把 JSON 示例的 { 当占位符 |
str.replace("{text}", text) |
7. Rerank 模块 ✅
- 新建
reranker.py— 调用硅基流动BAAI/bge-reranker-v2-m3 config.py新增RERANK_MODEL配置- 推送服务器验证 — 相关性评分 0.9993(相关文本),0.5947(部分相关),无关文本被正确排除
下午:CI/CD 流水线修复 + Gitea 升级
问题背景
提交 69dbf24(简化 deploy.yml)后,Gitea Actions 持续报错。排查过程发现逐层叠加的多个问题。
CI 流水线 8 个问题的排查与修复
| # | 现象 | 根因 | 修复 |
|---|---|---|---|
| 1 | CI 跑在 4核4G 而非 8核32G | runs-on: ubuntu-latest 匹配了 Runner 4(4核4G web runner),应该匹配 Runner 5(8核32G prod runner,标签 prod) |
deploy.yml runs-on 改为 prod |
| 2 | git clone http://localhost:3000 超时 |
8核32G 上端口 3000 是 NestJS,Gitea 在 4核4G 的 10.2.0.7:3000 |
clone URL 改为 http://10.2.0.7:3000 |
| 3 | cp 和 systemctl 权限不足 |
act_runner 以 ubuntu 用户运行,不能写 /etc/systemd/system/ |
加 sudo |
| 4 | /usr/bin/python3.11 不存在 |
CI 容器内无 Python 3.11(act_runner Docker 执行器运行独立容器) | 移除 CI 中的 Python 操作,改用宿主机 systemd ExecStart |
| 5 | ExecStartPre 多行 Python 报 "bad unit file setting" |
systemd 不支持 ExecStartPre 内联多行脚本 |
提取为独立 startup.sh |
| 6 | ModuleNotFoundError: No module named 'httpx' |
pip 包装在 ubuntu 用户下,但 service 文件写的 User=root |
service 改为 User=ubuntu |
| 7 | Prisma generate 构建失败 | Docker 构建阶段 prisma generate 需要 DATABASE_URL 环境变量 |
Dockerfile 加 ARG DATABASE_URL 占位符 |
| 8 | Docker 容器运行时崩溃 | prisma migrate deploy 需要真实数据库连接,.env 路径错误(/etc/zhixi/ vs /opt/zhixi/env/) |
最终放弃 Docker 部署,API 直接用 systemd 运行在宿主机 |
精简后的 CI 流程(最终版 deploy.yml)
经过多轮修复,CI 只保留 4 个步骤:
- Checkout —
git pull拉取最新代码(内网http://10.2.0.7:3000) - Ensure infrastructure —
docker start mysql redis qdrant - Deploy RAG Worker —
rsync→cp service→daemon-reload→restart→is-active - Health check —
curl http://localhost:3000/api
Gitea 1.22.6 的两个 bug
Bug 1:UpdateTask 返回 200 但不更新任务状态
现象:Runner 正确执行了所有 CI 步骤(日志完整记录到 🏁 Job succeeded),但 Gitea 数据库中 action_task.status 始终为 1 (waiting) 或 2 (running),不会变成 3 (success)。Run 65-68 状态卡在 running,Run 69 状态卡在 waiting。
排查过程:
- 检查 Gitea HTTP 日志 →
POST /api/actions/runner.v1.RunnerService/UpdateTask返回200 OK,每秒调用一次 - 检查 CI 日志存储 →
/data/gitea/actions_log/suche-Hermes/api-server/45/69.log已正常写入(32 行,3110 字节),内容以🏁 Job succeeded结尾 - 检查数据库 →
action_task、action_run_job、action_run三张表的状态字段均未更新 - 确认 runner journal 日志显示所有步骤成功执行
根因:Gitea 1.22.6 + act_runner v0.2.13 的组合 bug。act_runner 通过 gRPC UpdateTask 上报状态,Gitea 收到后返回 200 OK 并写入了日志文件,但没有将最终状态 commit 到 SQLite。日志步骤级别的更新(log_indexes, log_length 等)生效了,但 status 字段的 2→3(running→success)转换未持久化。
修复:手动在 Gitea SQLite 数据库中标记 Run 65-69 为成功:
UPDATE action_task SET status=3 WHERE id IN (65,66,67,68,69);
UPDATE action_run_job SET status=3 WHERE run_id IN (65,66,67,68,69);
UPDATE action_run SET status=3 WHERE id IN (65,66,67,68,69);
Bug 2:Actions 页面模板渲染崩溃(500 错误)
现象:访问 https://git.longde.cloud/suche-Hermes/api-server/actions 返回 500:
Render failed, failed to render template: repo/actions/list, error: template error:
builtin(bindata):repo/actions/status:26:36 : executing "repo/actions/status" at <or>:
wrong number of args for or: want at least 1 got 0
根因:Gitea 1.22.6 的编译版模板 templates/repo/actions/status.tmpl 第 26 行存在 Go 模板语法错误:
// ❌ 错误写法(v1.22.6)
{{else if or (eq .status "failure") or (eq .status "cancelled") or (eq .status "unknown")}}
// ✅ 正确写法(v1.23.8 已修复)
{{else if or (eq .status "failure") (or (eq .status "cancelled") (eq .status "unknown"))}}
Go 模板的 or 函数需要嵌套调用,多个 or 平级串联会导致参数数量解析错误。
修复:升级 Gitea 到 1.23.8(原地容器升级,数据无损):
# 备份数据库
cp /opt/gitea/data/gitea/gitea.db /opt/gitea/data/gitea/gitea.db.bak-20260520
# 停止旧容器,启动新版本
docker stop gitea && docker rm gitea
docker run -d --name gitea --restart always \
-p 3000:3000 -p 2222:22 \
-v /opt/gitea/data:/data \
-v /etc/timezone:/etc/timezone:ro \
-v /etc/localtime:/etc/localtime:ro \
gitea/gitea:1.23
升级后:
- Actions 页面恢复 200 OK,模板正常渲染
- 两个 runner(4核4G + 8核32G)自动重连
- 数据库完整无损
- 版本:Gitea 1.23.8, go1.23.9
CI 日志确认(Run 69 实际执行结果)
17:31:04 task 69 received, trigger: push
17:31:04 git pull → Fast-forward 69dbf24 (1 file changed)
17:31:04 docker start mysql redis qdrant → OK
17:31:06 [deploy] No failed migrations found
17:31:06 rsync rag-worker → /opt/zhixi/backend/rag-worker/ → sent 421 bytes
17:31:14 systemctl is-active zhixi-worker → active
17:31:14 [deploy] zhixi-worker active OK
17:31:14 GET /api → {"status":"ok"} → [deploy] API health OK
17:31:14 🏁 Job succeeded
最终验证结果
| 组件 | 状态 |
|---|---|
| Gitea | 1.23.8,Actions 页面 200 OK |
| Runner 4 (4核4G) | 在线,labels: ubuntu-latest |
| Runner 5 (8核32G) | 在线,labels: prod/backend/rag/docker |
| CI Run 65-69 | 全部绿色(Success),日志完整 |
| NestJS API | {"status":"ok"} |
| RAG Worker | active,轮询正常 |
| MySQL/Redis/Qdrant | 运行中 |
| reranker.py | bge-reranker-v2-m3 验证通过 |
当前待办
Python Worker 补全部署✅4核4G gitea-runner-web✅百度 OCR 开通✅COS Bucket 验证✅Rerank 模块代码 + 推送服务器验证✅CI/CD 流水线修复✅Gitea 升级 1.22.6 → 1.23.8✅- 🟡 知识库对话接口(RAG 检索→rerank→DeepSeek 回答+citations)
- 🟡 知识库级联删除
- 🟢 MySQL/Qdrant 备份脚本 + cron
- 🟢 物理清理定时任务
- ⬜ 阶段七:学习引擎(ActiveRecall→AIAnalysis→FocusItem→ReviewCard)
- ⬜ 阶段八:知识库对话(Chat session + 多轮对话)
- ⬜ 阶段十:后台管理 + 额度检查