#!/usr/bin/env bash # deploy.sh — Siemens RAGAS 一键部署脚本(Linux) # 用法:bash deploy.sh # 功能:检查环境 → 安装依赖 → 初始化配置 → 启动后台服务 set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" cd "$SCRIPT_DIR" # ── 颜色输出 ────────────────────────────────────────────────────── if [ -t 1 ]; then GREEN='\033[0;32m'; YELLOW='\033[1;33m'; RED='\033[0;31m'; CYAN='\033[0;36m'; NC='\033[0m' else GREEN=''; YELLOW=''; RED=''; CYAN=''; NC='' fi ok() { echo -e "${GREEN}[OK]${NC} $*"; } warn() { echo -e "${YELLOW}[WARN]${NC} $*"; } err() { echo -e "${RED}[ERROR]${NC} $*" >&2; } info() { echo -e "${CYAN}[INFO]${NC} $*"; } echo "" echo -e "${CYAN}============================================================${NC}" echo -e "${CYAN} Siemens RAGAS Console — Linux 一键部署${NC}" echo -e "${CYAN}============================================================${NC}" echo "" # ── 阶段 1:Python 版本检查 ─────────────────────────────────────── info "阶段 1/7:检查 Python 版本..." PYTHON_BIN="" for candidate in python3.12 python3.13 python3.14 python3; do if command -v "$candidate" &>/dev/null; then version=$("$candidate" -c "import sys; print(f'{sys.version_info.major}.{sys.version_info.minor}')" 2>/dev/null || true) major=$(echo "$version" | cut -d. -f1) minor=$(echo "$version" | cut -d. -f2) if [ "${major:-0}" -ge 3 ] && [ "${minor:-0}" -ge 12 ]; then PYTHON_BIN="$candidate" ok "Python $version ($candidate)" break fi fi done if [ -z "$PYTHON_BIN" ]; then err "未找到 Python 3.12+。请安装后重试。" err " Ubuntu/Debian: sudo apt install python3.12 python3.12-venv" err " CentOS/RHEL: sudo dnf install python3.12" exit 1 fi # ── 阶段 2:虚拟环境 ────────────────────────────────────────────── info "阶段 2/7:准备虚拟环境..." if [ -d ".venv" ] && [ -f ".venv/bin/python" ]; then ok ".venv 已存在,跳过创建" else info "创建 .venv..." "$PYTHON_BIN" -m venv .venv ok ".venv 创建完成" fi PIP=".venv/bin/pip" PYTHON=".venv/bin/python" # ── 阶段 3:安装依赖 ────────────────────────────────────────────── info "阶段 3/7:安装项目依赖(可能需要几分钟)..." "$PIP" install --upgrade pip -q ok "pip 已升级" "$PIP" install -e . -q ok "项目依赖安装完成(pyproject.toml)" "$PIP" install fastapi uvicorn httpx -q ok "Web 服务依赖安装完成(fastapi / uvicorn / httpx)" # ── 阶段 4:配置文件 ────────────────────────────────────────────── info "阶段 4/7:初始化配置文件..." if [ ! -f ".env" ]; then cp .env.example .env warn ".env 已从 .env.example 复制,请编辑填写实际的 API Key 等配置后再启动:" warn " nano .env 或 vim .env" warn " 关键字段:OPENAI_API_KEY, OPENAI_BASE_URL, ALIBABA_ACCESS_KEY_ID, ALIBABA_ACCESS_KEY_SECRET" else ok ".env 已存在,跳过" fi # ── 阶段 5:目录初始化 ──────────────────────────────────────────── info "阶段 5/7:初始化目录结构..." mkdir -p configs logs outputs datasets ok "目录就绪:configs/ logs/ outputs/ datasets/" # 确保其他脚本有执行权限 for script in start.sh stop.sh run_eval.sh; do [ -f "$script" ] && chmod +x "$script" done ok "辅助脚本已设置执行权限" # ── 阶段 6:Demo 数据 ───────────────────────────────────────────── info "阶段 6/7:初始化演示数据..." DEMO_DIR="outputs/kba-knowledge-base-offline-baseline" if [ -d "$DEMO_DIR" ]; then ok "演示数据已存在,跳过" else info "生成演示数据(scripts/seed_sample_run.py)..." if "$PYTHON" scripts/seed_sample_run.py; then ok "演示数据生成完成" else warn "演示数据生成失败,控制台报告页将为空(服务仍可正常启动)" fi fi # ── 阶段 7:启动服务 ────────────────────────────────────────────── info "阶段 7/7:启动 Web 服务..." # 检查 .env 是否包含默认占位符 if grep -q "your-api-key" .env 2>/dev/null; then warn ".env 中仍包含默认占位符,部分功能(评估执行)将不可用" warn "请编辑 .env 后重新运行 start.sh" fi # 端口检测 PORT=8800 if ss -tlnp 2>/dev/null | grep -q ":$PORT " || netstat -tlnp 2>/dev/null | grep -q ":$PORT "; then warn "端口 $PORT 已被占用,尝试 8801..." PORT=8801 if ss -tlnp 2>/dev/null | grep -q ":$PORT " || netstat -tlnp 2>/dev/null | grep -q ":$PORT "; then err "端口 8800 和 8801 均被占用。请手动运行:" err " .venv/bin/python webmain.py --host 0.0.0.0 --port " exit 1 fi fi # 清理残留 PID if [ -f ".server.pid" ]; then OLD_PID=$(cat .server.pid) if kill -0 "$OLD_PID" 2>/dev/null; then warn "检测到已有服务进程 (PID=$OLD_PID),停止旧进程..." kill "$OLD_PID" 2>/dev/null || true sleep 1 fi rm -f .server.pid fi # 后台启动 nohup "$PYTHON" webmain.py --host 0.0.0.0 --port "$PORT" >> logs/server.log 2>&1 & SERVER_PID=$! echo "$SERVER_PID" > .server.pid # 等待 3 秒验证进程存活 sleep 3 if kill -0 "$SERVER_PID" 2>/dev/null; then ok "服务已启动 (PID=$SERVER_PID)" echo "" echo -e "${CYAN}============================================================${NC}" echo -e "${GREEN} 部署成功!${NC}" echo -e "${GREEN} 访问地址: http://$(hostname -I | awk '{print $1}'):${PORT}${NC}" echo -e "${GREEN} 本机访问: http://127.0.0.1:${PORT}${NC}" echo -e "${CYAN} 服务日志: tail -f logs/server.log${NC}" echo -e "${CYAN} 停止服务: bash stop.sh${NC}" echo -e "${CYAN}============================================================${NC}" echo "" else err "服务启动失败,请查看日志:" err " tail -20 logs/server.log" rm -f .server.pid exit 1 fi