# Linux 一键部署脚本设计 **日期**: 2026-06-22 **状态**: 已批准,待实现 **范围**: 为 siemens_ragas 项目提供 Linux 环境的部署与运维脚本(无 Docker,无 systemd)。 --- ## 1. 目标 提供四个 Bash 脚本,覆盖 Linux 服务器上的完整生命周期: | 脚本 | 职责 | |------|------| | `deploy.sh` | 一键完成环境检查、依赖安装、配置初始化、启动服务 | | `start.sh` | 仅启动 Web 服务(已部署后复用,不重装依赖) | | `stop.sh` | 停止后台 Web 服务 | | `run_eval.sh` | 运行单次评估(对应 Windows 的 `run_eval.ps1`) | --- ## 2. 约束与假设 - Linux 目标环境有 PyPI 网络访问(pip 可直接安装) - 代码已通过 `git clone` 或文件拷贝到服务器 - 使用 `pip + venv`(不使用 uv) - Web 服务监听 `0.0.0.0:8800`(内网可达) - 后台运行使用 `nohup`,PID 写入 `.server.pid`,日志追加到 `logs/server.log` - 所有脚本均放在仓库根目录,路径相对于 `$SCRIPT_DIR` --- ## 3. `deploy.sh` 详细设计 ### 3.1 阶段 1:Python 版本检查 ``` require Python >= 3.12 ``` - `python3 --version` 解析 major.minor - 不满足则打印错误并 `exit 1` - 满足则打印 `[OK] Python X.Y.Z` ### 3.2 阶段 2:虚拟环境 - 目标路径:`$SCRIPT_DIR/.venv` - 已存在则跳过创建(打印 `[OK] .venv already exists`) - 不存在则 `python3 -m venv .venv` ### 3.3 阶段 3:依赖安装 ```bash .venv/bin/pip install --upgrade pip -q .venv/bin/pip install -e . -q # 安装 pyproject.toml 中的依赖 .venv/bin/pip install fastapi uvicorn httpx -q # Web 服务额外依赖 ``` - 失败则打印错误并 `exit 1` - `fastapi`、`uvicorn`、`httpx` 在 `pyproject.toml` 中未列,需单独安装 ### 3.4 阶段 4:配置文件 - 若 `.env` 不存在:`cp .env.example .env`,打印警告提示用户编辑后再启动 - 若 `.env` 已存在:跳过,打印 `[OK] .env found` ### 3.5 阶段 5:目录初始化 创建以下目录(`mkdir -p`,幂等): - `configs/` — LLM Profile 持久化存储 - `logs/` — 评估日志 + 服务器日志 - `outputs/` — 评估运行产物 - `datasets/` — 原始数据集 ### 3.6 阶段 6:Demo 数据 - 检查 `outputs/kba-knowledge-base-offline-baseline/` 是否存在 - 不存在则运行 `.venv/bin/python scripts/seed_sample_run.py` - 失败时打印 `[WARN]`(非致命,报告页为空但服务可启动) ### 3.7 阶段 7:端口检测 - 默认端口 `8800` - 用 `ss -tlnp` 或 `netstat -tlnp` 检查是否占用 - 占用则尝试 `8801`,仍占用则报错退出 ### 3.8 阶段 8:启动服务 ```bash nohup .venv/bin/python webmain.py \ --host 0.0.0.0 \ --port $PORT \ >> logs/server.log 2>&1 & echo $! > .server.pid ``` - 等待 2 秒后用 `kill -0 $PID` 检测进程是否存活 - 存活则打印 URL 和 stop 方法 - 未存活则打印 `[ERROR] Server failed to start. Check logs/server.log.` 并 `exit 1` --- ## 4. `start.sh` 详细设计 单独负责启动,不做任何环境初始化。 ```bash #!/usr/bin/env bash # 检查 .venv 存在 # 端口检测(同 deploy.sh 逻辑) # 检查 .env 存在(不存在则 warn 但不阻止) # nohup 启动 + PID 文件 + 存活验证 # 打印 URL ``` --- ## 5. `stop.sh` 详细设计 ```bash #!/usr/bin/env bash # 读取 .server.pid # 若文件不存在:打印 "No server PID file found." 退出 # kill $PID # 等待 2 秒,若进程仍存活用 kill -9 # 删除 .server.pid # 打印 "Server stopped." ``` --- ## 6. `run_eval.sh` 详细设计 对应 Windows 的 `run_eval.ps1`。 ``` 用法: ./run_eval.sh # online eval (默认) ./run_eval.sh offline # offline smoke ./run_eval.sh scenarios/xxx.yaml # 自定义场景 ./run_eval.sh online DEBUG # 自定义日志级别 ``` - 参数 1(Scenario):`online` / `offline` / 文件路径,默认 `online` - 参数 2(LogLevel):`DEBUG` / `INFO` / `WARNING` / `ERROR`,默认 `INFO` - 场景别名映射: - `online` → `scenarios/online/siemens-pdf-question-bank-online.yaml` - `offline` → `scenarios/offline/siemens-pdf-offline-smoke.yaml` - 时间戳日志文件:`logs/eval_$(date +%Y-%m-%d_%H%M%S).log` - 环境变量:`PYTHONIOENCODING=utf-8 PYTHONPATH=.` - 调用:`.venv/bin/python main.py --scenario $SCENARIO --log-file $LOG_FILE --log-level $LOG_LEVEL` - 非零退出码时打印错误并 `exit 1` --- ## 7. 通用约定 - 所有脚本首行:`#!/usr/bin/env bash` - `set -euo pipefail` — 错误立即退出,未定义变量报错,管道错误传播 - `SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"` — 从任意目录执行均正确 - `cd "$SCRIPT_DIR"` — 切换到仓库根目录 - 颜色输出:绿色 `[OK]`、黄色 `[WARN]`、红色 `[ERROR]`(检测 tty,非交互式终端降级为无色) - 执行权限:脚本自身需要 `chmod +x`(在 deploy.sh 内对其他脚本自动 chmod) --- ## 8. 不在范围内 - Docker / docker-compose 支持 - systemd service 配置 - Nginx 反向代理配置 - SSL/TLS 配置 - 离线/内网镜像源配置