174 lines
6.6 KiB
Bash
174 lines
6.6 KiB
Bash
|
|
#!/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 <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
|