#!/usr/bin/env bash # deploy/qa-db/install_qdrant.sh —— PlantAI QA 数据库裸进程标准:Qdrant # 用法(需 root): # sudo -S bash install_qdrant.sh [QA_DB_ROOT] [HTTP_PORT] [GRPC_PORT] # QA_DB_ROOT 默认 <安装根>/qa-db(release 树中即 install 的上一级;仓库树中即仓库根) # HTTP_PORT 默认 27433;GRPC_PORT 默认 27434 # (与 docker 共享实例 27333/27334 互不冲突,175 上容器为其他项目服务、不动) # 产物:/usr/local/bin/qdrant、/etc/qdrant/config.yaml、systemd 单元 qdrant-plantai.service # 数据目录:$QA_DB_ROOT/qdrant/storage(整库替换见 replace_db.sh) # 版本默认 v1.18.3(与 2026-08 容器实例 qdrant/qdrant:latest 对齐) set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" INSTALL_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" QA_DB_ROOT="${1:-${QA_DB_ROOT:-$INSTALL_ROOT/qa-db}}" HTTP_PORT="${2:-27433}" GRPC_PORT="${3:-27434}" QDRANT_VERSION="${QDRANT_VERSION:-v1.18.3}" RUN_USER="${RUN_USER:-${SUDO_USER:-xzq}}" BIN=/usr/local/bin/qdrant CONF=/etc/qdrant/config.yaml UNIT=/etc/systemd/system/qdrant-plantai.service STORAGE="$QA_DB_ROOT/qdrant/storage" TPL="$SCRIPT_DIR/qdrant.service" [[ $EUID -eq 0 ]] || { echo "需要 root:sudo -S bash $0 $*" >&2; exit 1; } command -v curl >/dev/null || { echo "缺少 curl(apt install -y curl)" >&2; exit 1; } id -u "$RUN_USER" >/dev/null 2>&1 || { echo "运行用户不存在:$RUN_USER" >&2; exit 1; } # 1) 二进制(版本已符合则跳过;官方静态二进制,免编译) if [[ -x "$BIN" ]] && "$BIN" --version 2>/dev/null | grep -q "$QDRANT_VERSION"; then echo "[qdrant] 二进制已就绪:$("$BIN" --version 2>&1 | head -1)" else # 优先使用随包携带的本地二进制(离线/受限网络部署时从构建机 scp 到此目录) LOCAL_BIN="$SCRIPT_DIR/bin/qdrant" if [[ -x "$LOCAL_BIN" ]] && "$LOCAL_BIN" --version 2>/dev/null | grep -q "$QDRANT_VERSION"; then echo "[qdrant] 使用本地二进制:$LOCAL_BIN" install -m 0755 "$LOCAL_BIN" "$BIN" else echo "[qdrant] 下载 qdrant $QDRANT_VERSION ..." URLS=( "https://github.com/qdrant/qdrant/releases/download/$QDRANT_VERSION/qdrant-x86_64-unknown-linux-gnu.tar.gz" "https://gh-proxy.com/https://github.com/qdrant/qdrant/releases/download/$QDRANT_VERSION/qdrant-x86_64-unknown-linux-gnu.tar.gz" "https://ghfast.top/https://github.com/qdrant/qdrant/releases/download/$QDRANT_VERSION/qdrant-x86_64-unknown-linux-gnu.tar.gz" ) ok=0 for u in "${URLS[@]}"; do if curl -fL --connect-timeout 10 --max-time 300 -o /tmp/qdrant.tar.gz "$u" 2>/dev/null; then ok=1; echo "[qdrant] 下载成功:$u"; break fi echo "[qdrant] 下载失败,换下一源:$u" done [[ $ok -eq 1 ]] || { echo "所有下载源失败,请手动放置二进制到 $BIN 或 $LOCAL_BIN" >&2; exit 1; } tar -xzf /tmp/qdrant.tar.gz -C /tmp install -m 0755 /tmp/qdrant "$BIN" rm -f /tmp/qdrant.tar.gz /tmp/qdrant "$BIN" --version | head -1 fi fi # 2) 数据目录 + 配置(config 由本脚本参数生成,不手改) mkdir -p "$STORAGE" /etc/qdrant cat > "$CONF" < "$UNIT" # 4) 幂等启动 + 探活 systemctl daemon-reload systemctl enable --now qdrant-plantai.service >/dev/null 2>&1 || true for _ in $(seq 1 30); do if curl -sf --max-time 2 "http://127.0.0.1:$HTTP_PORT/collections" >/dev/null 2>&1; then echo "[qdrant] UP http://127.0.0.1:$HTTP_PORT (storage: $STORAGE)" exit 0 fi sleep 2 done echo "[qdrant] 启动失败:journalctl -u qdrant-plantai -n 50" >&2 exit 1