diff --git a/README.md b/README.md index 430107d..3afcab0 100755 --- a/README.md +++ b/README.md @@ -242,7 +242,7 @@ bash _run.sh # 运行 部署路径约定为 `/opt/micro_servers/`,`core` 的 `init.txt` 即从该路径拉起其余服务。 -> **注意**:`ai_review` 未包含在 `_inst.sh` 中,需进入 `ai_review/` 目录执行 `_set.sh` 安装,并额外配置 `.env` 文件(DeepSeek API 密钥等)。 +> **注意**:`ai_review` / `aibox` / `redirect80` 已纳入 `_inst.sh`(分别依赖 chromadb ONNX 模型下载、`~/.cert/deepseek.key`、本地 `pymsg` 包)。`ai_review` 额外需配置 `.env` 文件(DeepSeek API 密钥等,参考 [ai_review/README.md](ai_review/README.md))。 > **注意**:waf 首次编译需联网下载 Go 依赖,[waf/_set.sh](waf/_set.sh) 会自动调用 [waf/_goproxy.sh](waf/_goproxy.sh) 设置 GOPROXY 国内镜像。如需手动设置:`go env -w GOPROXY=https://goproxy.cn,direct`。 diff --git a/_inst.sh b/_inst.sh index 7dbab8a..eb2f042 100755 --- a/_inst.sh +++ b/_inst.sh @@ -38,4 +38,7 @@ inst_module "db" inst_module "smtp" inst_module "captcha" inst_module "confs" +inst_module "ai_review" # 需联网拉 chromadb onnx 模型(_fetch_onnx_model.sh 走 ModelScope 镜像) +inst_module "aibox" # 需 ~/.cert/deepseek.key(见 _setenv.sh) +inst_module "redirect80" # 80 端口重定向,依赖 ../pymsg inst_module "core" # core last diff --git a/ai_review/_fetch_onnx_model.sh b/ai_review/_fetch_onnx_model.sh new file mode 100755 index 0000000..25f9584 --- /dev/null +++ b/ai_review/_fetch_onnx_model.sh @@ -0,0 +1,68 @@ +#!/bin/bash +# ============================================================ +# _fetch_onnx_model.sh — 预下载 chromadb ONNX 嵌入模型 +# ------------------------------------------------------------ +# chromadb 默认从 AWS S3 拉取 all-MiniLM-L6-v2 (onnx.tar.gz), +# 国内直连极慢(~18KB/s)且失败会导致 ai_review 无法启动。 +# 本脚本改为从 ModelScope 镜像逐个下载 chroma 所需的 6 个文件, +# 放到 chromadb 的缓存目录,跳过其内置下载逻辑。 +# +# 可配置: +# ONNX_MODEL_BASE_URL 模型仓库 base URL(默认 ModelScope 镜像) +# CHROMA_CACHE_DIR chroma 缓存根目录(默认 $HOME/.cache/chroma) +# ============================================================ +set -uo pipefail + +CACHE_ROOT="${CHROMA_CACHE_DIR:-$HOME/.cache/chroma}" +DEST_DIR="$CACHE_ROOT/onnx_models/all-MiniLM-L6-v2/onnx" +BASE_URL="${ONNX_MODEL_BASE_URL:-https://modelscope.cn/models/AI-ModelScope/all-MiniLM-L6-v2/resolve/master}" + +# chromadb ONNXMiniLM_L6_V2._download_model_if_not_exists 检查的文件 +FILES=( + "config.json" + "model.onnx" + "special_tokens_map.json" + "tokenizer_config.json" + "tokenizer.json" + "vocab.txt" +) + +echo "[fetch-onnx] 目标目录: $DEST_DIR" +mkdir -p "$DEST_DIR" + +# 已有完整模型则跳过 +need=0 +for f in "${FILES[@]}"; do + [ -s "$DEST_DIR/$f" ] || need=1 +done +if [ "$need" = "0" ]; then + echo "[fetch-onnx] 模型已存在,跳过下载" + exit 0 +fi + +fail=0 +for f in "${FILES[@]}"; do + if [ -s "$DEST_DIR/$f" ]; then + echo "[fetch-onnx] $f 已存在,跳过" + continue + fi + # model.onnx 在仓库 onnx/ 子目录,其余在根目录 + if [ "$f" = "model.onnx" ]; then + url="$BASE_URL/onnx/$f" + else + url="$BASE_URL/$f" + fi + echo "[fetch-onnx] 下载 $f <- $url" + if ! curl -fsSL --retry 3 --connect-timeout 15 -o "$DEST_DIR/$f" "$url"; then + echo "[fetch-onnx] ⚠ 下载 $f 失败" >&2 + fail=1 + fi +done + +if [ "$fail" = "1" ]; then + echo "[fetch-onnx] ⚠ 部分文件下载失败,ai_review 启动时 chromadb 会尝试原 S3 下载" >&2 + exit 1 +fi + +echo "[fetch-onnx] ✅ 完成,文件清单:" +ls -la "$DEST_DIR" diff --git a/ai_review/_set.sh b/ai_review/_set.sh index 61e616a..77bc48e 100644 --- a/ai_review/_set.sh +++ b/ai_review/_set.sh @@ -4,5 +4,9 @@ python3 -m venv venv #sudo chmod +x .env/bin/activate source venv/bin/activate pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple + +# 预下载 chromadb ONNX 嵌入模型(默认 ModelScope 镜像,避免 AWS S3 国内直连超时) +# 可用 ONNX_MODEL_BASE_URL 覆盖镜像源;失败不阻塞安装,但 ai_review 启动时可能需手动处理 +bash _fetch_onnx_model.sh || echo "⚠ onnx 模型下载失败,可稍后重跑 bash _fetch_onnx_model.sh" #nuitka --onefile --jobs=1 dnfs.py diff --git a/docs/INDEX.md b/docs/INDEX.md index edfcba8..c21ceea 100644 --- a/docs/INDEX.md +++ b/docs/INDEX.md @@ -59,6 +59,7 @@ docs/ | 文档 | 说明 | |------|------| | [core_CODE_REVIEW_LOG_20260730.md](reviews/core_CODE_REVIEW_LOG_20260730.md) | Core 模块代码审查日志(2026-07-30,自动化审查) | +| [DEPLOY_DEFECT_AUDIT_20260806.md](reviews/DEPLOY_DEFECT_AUDIT_20260806.md) | 部署缺陷审查(2026-08-06,首次原生部署实录,含修复记录) | --- diff --git a/docs/reviews/DEPLOY_DEFECT_AUDIT_20260806.md b/docs/reviews/DEPLOY_DEFECT_AUDIT_20260806.md new file mode 100644 index 0000000..cd5e992 --- /dev/null +++ b/docs/reviews/DEPLOY_DEFECT_AUDIT_20260806.md @@ -0,0 +1,96 @@ +# blackbird 部署缺陷审查报告(2026-08-06) + +> 来源:2026-08-06 首次原生编译部署全流程观察(qsont 运维实录) +> 范围:`_inst.sh` 构建链、systemd 单元、chromadb 模型下载、key 路径约定等部署/运维相关代码缺陷 +> 状态标记:🔴 高(影响可靠性) 🟡 中(坑人/影响开发) 🟢 低(文档/非功能) + +--- + +## 🔴 高(影响可靠性) + +### 1. Nidus.service 没有 `Restart=` 配置 + +- **位置**:`core/Nidus.service` +- **问题**:README 声称"崩溃守护由 systemd 负责",但 service 文件只有 `ExecStart`,systemd 默认 `Restart=no`。 +- **影响**:nidus 一旦崩溃不会被拉起,12 个服务全部停摆,且无告警。 +- **建议**:加 `Restart=on-failure` + `RestartSec=5`。 + +### 2. `_inst.sh` 遗漏 3 个模块(已修复 ✅) + +- **位置**:`_inst.sh`(本次已修复) +- **问题**:ai_review、aibox、redirect80 不在构建列表,README 只提到 ai_review 需单独安装。 +- **影响**:按 README 部署的人会发现 init.txt 引用的服务有 3 个没装。 +- **修复**:已补入 `_inst.sh`(confs 之后、core 之前),并更新 README 说明。 + +### 3. chromadb 模型从 AWS S3 硬编码下载(已修复 ✅) + +- **位置**:chromadb 第三方库 `onnx_mini_lm_l6_v2.py`(`MODEL_DOWNLOAD_URL` 写死 S3) +- **问题**:国内直连 18KB/s,90MB 模型要 1 小时+,下载失败直接抛异常导致服务起不来。 +- **影响**:ai_review 在国内环境首次启动必挂。 +- **修复**:新增 `ai_review/_fetch_onnx_model.sh`,默认从 ModelScope 镜像下载(560KB/s),支持 `ONNX_MODEL_BASE_URL` / `CHROMA_CACHE_DIR` 环境变量覆盖,断点续传 + 幂等;`ai_review/_set.sh` 自动调用。 + +### 4. key 路径硬编码 + 运行身份不一致 + +- **位置**:`aibox/_setenv.sh`(读 `~/.cert/deepseek.key`) +- **问题**:Nidus 以 root 运行,root 的 `~` 与 qing 的 `~` 不是同一路径,部署时缺 key 服务启动即崩(RuntimeError),日志难排查。 +- **影响**:aibox / ai_review 缺 DeepSeek key 时静默崩溃。 +- **建议**:改为环境变量优先,fallback 到 `/root/.cert/` 与 `/home//.cert/` 多路径探测。 + +--- + +## 🟡 中(坑人/影响开发) + +### 5. `waf/_gen.sh` 产物与配置不匹配 + +- **位置**:`waf/_gen.sh`、`waf/config.yaml` +- **问题**:脚本生成 `server.crt`,配置要求 `certs/full_chain.crt`,需手动改名/移动。 +- **建议**:脚本直接输出到 `certs/` 目录并命名 `full_chain.crt`。 + +### 6. pymsg 构建产物属主污染 + +- **位置**:`pymsg/`(egg-info / build 目录) +- **问题**:`_inst.sh` 以 root 运行,构建产物变成 root 属主,之后 qing 用户再构建报 "Cannot update time stamp"。 +- **建议**:构建脚本里 `chown` 回原用户,或明确要求统一以 root 构建。 + +### 7. core Makefile install 注释掉 `mkdir -p` + +- **位置**:`core/Makefile`(`#@mkdir -p $(INSTL_DIRS)`) +- **问题**:依赖目标目录预存在,`/usr/local/bin` 恰好存在所以未炸,属隐藏脆弱点。 +- **建议**:取消注释。 + +### 8. `captcha/_set.sh` 复制粘贴错误 + +- **位置**:`captcha/_set.sh` +- **问题**:nuitka 注释行写的是 `smtp.py` 而非 `captcha.py`(照抄 smtp)。 +- **建议**:修正为 `captcha_service.py`。 + +--- + +## 🟢 低(文档/非功能) + +### 9. 部署树创建无文档 + +- **位置**:README 部署章节 +- **问题**:`make install` 只装二进制和 systemd 单元,`/opt/micro_servers` 需自行创建,首次部署必踩 127。 +- **建议**:README 补充 `mkdir -p /opt/micro_servers` 与同步命令。 + +### 10. docker-compose 与原生部署并存 + +- **位置**:`docker-compose.yml` +- **问题**:compose 中 db/ai_review/dnfs 端口与原生部署冲突,切换方式未文档化。 +- **建议**:README 说明两种模式互斥,或提供 `docker.sh` 切换脚本说明。 + +### 11. `.env` 无模板 + +- **位置**:`ai_review/` +- **问题**:依赖 README 贴示例,无 `.env.example`,漏配一个 key 就是启动崩溃。 +- **建议**:提供 `.env.example` 并纳入 git。 + +--- + +## 优先级建议 + +1. **#1 Restart 策略** — 一行 systemd 配置,消除生产事故级隐患 +2. **#4 key 路径探测** — 消除部署时静默崩溃 +3. **#5-#8** — 开发体验类,随手可改 +4. **#9-#11** — 文档类,随 README 更新一起做