refactor(postgresql): replace zhparser+scws with pg_jieba; update Makefile and setup scripts
This commit is contained in:
parent
2a945adb6f
commit
3edad8474c
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,4 +1,5 @@
|
||||
models/
|
||||
pg_jieba/
|
||||
hf_cache/
|
||||
server/server/
|
||||
docs/init-bak-20250813.sql
|
||||
|
||||
75
Makefile
75
Makefile
@ -1,15 +1,17 @@
|
||||
OS := $(shell uname -s)
|
||||
SHELL := /bin/bash
|
||||
O_BIN ?= /usr/local/go/bin
|
||||
PG_DSN ?= postgres://shenlan:password@127.0.0.1:5432/xserver?sslmode=disable
|
||||
PG_MAJOR ?= 16
|
||||
NODE_MAJOR ?= 22
|
||||
ARCH := $(shell dpkg --print-architecture)
|
||||
PG_DSN ?= postgres://shenlan:password@127.0.0.1:5432/xserver?sslmode=disable
|
||||
|
||||
export PATH := $(GO_BIN):$(PATH)
|
||||
|
||||
.PHONY: install install-openresty install-redis install-postgresql init-db \
|
||||
build update-dashboard-manifests build-server build-dashboard \
|
||||
start start-openresty start-server start-dashboard \
|
||||
stop stop-server stop-dashboard stop-openresty restart
|
||||
stop stop-server stop-dashboard stop-openresty restart lint-cms
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Dependency installation
|
||||
@ -17,19 +19,19 @@ stop stop-server stop-dashboard stop-openresty restart
|
||||
|
||||
install: install-nodejs install-go install-openresty install-redis install-postgresql
|
||||
|
||||
# --- Node.js ---------------------------------------------------------------
|
||||
install-nodejs:
|
||||
ifeq ($(OS),Darwin)
|
||||
# 尽量装新 LTS;若 node@22 不可用,可退回 brew install node
|
||||
( brew install node@22 && brew link --overwrite --force node@22 ) || brew install node
|
||||
# 启用 Corepack + Yarn
|
||||
corepack enable || true
|
||||
corepack prepare yarn@stable --activate || true
|
||||
@echo "Node: $$(node -v)"; echo "Yarn: $$(yarn -v 2>/dev/null || echo n/a)"
|
||||
@echo "✅ Node: $$(node -v)"; echo "✅ Yarn: $$(yarn -v 2>/dev/null || echo n/a)"
|
||||
else
|
||||
@echo "Using setup_ubuntu_2204.sh to install Node.js..."
|
||||
@echo "🟦 Installing Node.js $(NODE_MAJOR) via setup_ubuntu_2204.sh..."
|
||||
NODE_MAJOR=$(NODE_MAJOR) bash scripts/setup_ubuntu_2204.sh install-nodejs
|
||||
endif
|
||||
|
||||
# --- Go --------------------------------------------------------------------
|
||||
install-go:
|
||||
ifeq ($(OS),Darwin)
|
||||
brew install go
|
||||
@ -37,43 +39,52 @@ else
|
||||
GO_VERSION=$(GO_VERSION) bash scripts/setup_ubuntu_2204.sh install-go
|
||||
endif
|
||||
|
||||
# --- OpenResty -------------------------------------------------------------
|
||||
install-openresty:
|
||||
ifeq ($(OS),Darwin)
|
||||
@[ -f install-openresty.sh ] && bash install-openresty.sh
|
||||
else
|
||||
@echo "Detected Linux. Installing via apt..."
|
||||
sudo apt-get update && \
|
||||
sudo apt-get install -y openresty || echo "Please install OpenResty manually."
|
||||
@$(MAKE) start-openresty
|
||||
endif
|
||||
@echo "🚀 Installing OpenResty using external script..."
|
||||
@bash scripts/install-openresty.sh; \
|
||||
|
||||
# --- Redis -----------------------------------------------------------------
|
||||
install-redis:
|
||||
ifeq ($(OS),Darwin)
|
||||
brew install redis && brew services start redis
|
||||
else
|
||||
@echo "Using setup_ubuntu_2204.sh to install Redis..."
|
||||
@echo "🟥 Installing Redis via setup_ubuntu_2204.sh..."
|
||||
bash scripts/setup_ubuntu_2204.sh install-redis
|
||||
endif
|
||||
|
||||
# --- PostgreSQL ------------------------------------------------------------
|
||||
install-postgresql:
|
||||
ifeq ($(OS),Darwin)
|
||||
brew install postgresql@16 && \
|
||||
brew services start postgresql@16 && \
|
||||
brew install pgvector && \
|
||||
brew install scws && \
|
||||
tmp_dir=$$(mktemp -d) && cd $$tmp_dir && \
|
||||
git clone https://github.com/amutu/zhparser.git && \
|
||||
cd zhparser && make SCWS_HOME=/opt/homebrew PG_CONFIG=$$(brew --prefix postgresql@16)/bin/pg_config && \
|
||||
sudo make install SCWS_HOME=/opt/homebrew PG_CONFIG=$$(brew --prefix postgresql@16)/bin/pg_config && \
|
||||
cd / && rm -rf $$tmp_dir
|
||||
@set -e; \
|
||||
echo "🍎 Installing PostgreSQL 16 via Homebrew..."; \
|
||||
brew install postgresql@16 || true; \
|
||||
brew services start postgresql@16; \
|
||||
echo "📦 Installing pgvector extension..."; \
|
||||
brew install pgvector || true; \
|
||||
echo "📦 Installing pg_jieba (替代 zhparser + scws)..."; \
|
||||
tmp_dir=$$(mktemp -d) && cd $$tmp_dir && \
|
||||
git clone --recursive https://github.com/jaiminpan/pg_jieba.git && \
|
||||
cd pg_jieba && mkdir build && cd build && \
|
||||
cmake -DPostgreSQL_TYPE_INCLUDE_DIR=$$(brew --prefix postgresql@16)/include/postgresql/server .. && \
|
||||
make -j$$(sysctl -n hw.ncpu) && sudo make install && \
|
||||
cd / && rm -rf $$tmp_dir; \
|
||||
echo "✅ PostgreSQL extensions installed successfully!"
|
||||
else
|
||||
@set -e; \
|
||||
echo "Using setup-ubuntu-2204.sh to install PostgreSQL 16..."; \
|
||||
echo "🟨 Installing PostgreSQL 16..."; \
|
||||
bash scripts/setup_ubuntu_2204.sh install-postgresql; \
|
||||
echo "Using setup-ubuntu-2204.sh to install pgvector..."; \
|
||||
echo "🟨 Installing pgvector extension..."; \
|
||||
bash scripts/setup_ubuntu_2204.sh install-pgvector; \
|
||||
echo "Using setup-ubuntu-2204.sh to install zhparser..."; \
|
||||
bash scripts/setup_ubuntu_2204.sh install-zhparser
|
||||
echo "🟨 Installing pg_jieba extension (替代 zhparser + scws)..."; \
|
||||
tmp_dir=$$(mktemp -d) && cd $$tmp_dir && \
|
||||
sudo apt-get install -y cmake g++ git postgresql-server-dev-${PG_MAJOR}; \
|
||||
git clone --recursive https://github.com/jaiminpan/pg_jieba.git && \
|
||||
cd pg_jieba && mkdir build && cd build && \
|
||||
cmake -DPostgreSQL_TYPE_INCLUDE_DIR=/usr/include/postgresql/${PG_MAJOR}/server .. && \
|
||||
make -j$$(nproc) && sudo make install && \
|
||||
cd / && rm -rf $$tmp_dir; \
|
||||
echo "✅ PostgreSQL extensions installed successfully!"
|
||||
endif
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
@ -85,7 +96,6 @@ init-db:
|
||||
# -----------------------------------------------------------------------------
|
||||
# Build targets
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
build: update-dashboard-manifests build-cli build-server build-dashboard
|
||||
|
||||
build-cli:
|
||||
@ -103,8 +113,7 @@ update-dashboard-manifests:
|
||||
# -----------------------------------------------------------------------------
|
||||
# Run targets
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
start: start-openresty start-server start-dashboard start-dl start-docs
|
||||
start: start-openresty start-server start-dashboard
|
||||
|
||||
start-server:
|
||||
$(MAKE) -C rag-server start
|
||||
@ -112,7 +121,6 @@ start-server:
|
||||
start-dashboard:
|
||||
$(MAKE) -C dashboard start
|
||||
|
||||
|
||||
stop: stop-server stop-dashboard stop-openresty
|
||||
|
||||
stop-server:
|
||||
@ -141,7 +149,7 @@ ifeq ($(OS),Darwin)
|
||||
> ~/Library/LaunchAgents/homebrew.mxcl.openresty.plist && \
|
||||
brew services start ~/Library/LaunchAgents/homebrew.mxcl.openresty.plist )
|
||||
else
|
||||
sudo systemctl enable --now openresty
|
||||
sudo systemctl enable --now openresty || echo "⚠️ openresty.service missing or inactive"
|
||||
endif
|
||||
|
||||
stop-openresty:
|
||||
@ -156,6 +164,5 @@ restart: stop start
|
||||
# -----------------------------------------------------------------------------
|
||||
# CMS configuration validation
|
||||
# -----------------------------------------------------------------------------
|
||||
.PHONY: lint-cms
|
||||
lint-cms:
|
||||
python3 scripts/validate_cms_config.py
|
||||
|
||||
@ -1,44 +1,43 @@
|
||||
-- ================================================
|
||||
-- init.sql - Stable RAG schema with Hybrid Search
|
||||
-- For pgvector ≥ 0.5, BGE-M3 (1024 dims), zhparser+english
|
||||
-- For pgvector ≥ 0.5, BGE-M3 (1024 dims), pg_jieba + english
|
||||
-- ================================================
|
||||
|
||||
-- 1. 避免锁表/阻塞
|
||||
SET lock_timeout = '5s';
|
||||
SET statement_timeout = '0';
|
||||
|
||||
-- 2. 必要扩展(向量 + 中文分词)
|
||||
-- 1. 必要扩展:向量 + 中文分词
|
||||
CREATE EXTENSION IF NOT EXISTS vector;
|
||||
CREATE EXTENSION IF NOT EXISTS zhparser;
|
||||
CREATE EXTENSION IF NOT EXISTS pg_jieba;
|
||||
|
||||
-- 3. 中文+ 英文混合全文检索配置(zhparser + simple)
|
||||
-- 自定义配置名:zhcn_search
|
||||
-- 2. 中文 + 英文混合全文检索配置(pg_jieba + simple)
|
||||
-- 自定义配置名:jieba_search
|
||||
DO $$
|
||||
BEGIN
|
||||
IF NOT EXISTS (SELECT 1 FROM pg_ts_config WHERE cfgname = 'zhcn_search') THEN
|
||||
CREATE TEXT SEARCH CONFIGURATION zhcn_search (PARSER = zhparser);
|
||||
ALTER TEXT SEARCH CONFIGURATION zhcn_search
|
||||
ADD MAPPING FOR n,v,a,i,e,l WITH simple;
|
||||
IF NOT EXISTS (SELECT 1 FROM pg_ts_config WHERE cfgname = 'jieba_search') THEN
|
||||
CREATE TEXT SEARCH CONFIGURATION jieba_search (PARSER = pg_jieba);
|
||||
-- pg_jieba 的 token 类型包括:word, tag, symbol, number
|
||||
ALTER TEXT SEARCH CONFIGURATION jieba_search
|
||||
ADD MAPPING FOR word, tag, symbol, number WITH simple;
|
||||
END IF;
|
||||
END$$;
|
||||
|
||||
-- 4. 创建主表
|
||||
-- 3. 主表结构
|
||||
CREATE TABLE IF NOT EXISTS public.documents (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
repo TEXT NOT NULL,
|
||||
path TEXT NOT NULL,
|
||||
chunk_id INT NOT NULL,
|
||||
content TEXT NOT NULL,
|
||||
embedding VECTOR(1024), -- 向量字段(bge-m3)
|
||||
embedding VECTOR(1024),
|
||||
metadata JSONB,
|
||||
content_sha TEXT NOT NULL,
|
||||
|
||||
-- 中文+英文全文搜索字段
|
||||
-- 全文检索字段(pg_jieba)
|
||||
content_tsv tsvector GENERATED ALWAYS AS (
|
||||
setweight(to_tsvector('zhcn_search', coalesce(content, '')), 'A')
|
||||
setweight(to_tsvector('jieba_search', coalesce(content, '')), 'A')
|
||||
) STORED,
|
||||
|
||||
-- 文档唯一标识(组合键 doc_key)
|
||||
doc_key TEXT GENERATED ALWAYS AS (
|
||||
repo || ':' || path || ':' || chunk_id
|
||||
) STORED,
|
||||
@ -47,20 +46,20 @@ CREATE TABLE IF NOT EXISTS public.documents (
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
-- 5. 唯一约束(支持 UPSERT)
|
||||
-- 4. 唯一约束
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS documents_doc_key_uk
|
||||
ON public.documents (doc_key);
|
||||
|
||||
-- 6. 向量索引(仅索引非空 embedding)
|
||||
-- 5. 向量索引
|
||||
CREATE INDEX IF NOT EXISTS documents_embedding_idx
|
||||
ON public.documents
|
||||
USING hnsw (embedding vector_cosine_ops)
|
||||
WHERE embedding IS NOT NULL;
|
||||
|
||||
-- 7. 全文索引(中文 + 英文,使用 zhcn_search)
|
||||
-- 6. 全文索引(pg_jieba)
|
||||
CREATE INDEX IF NOT EXISTS idx_documents_tsv
|
||||
ON public.documents USING gin (content_tsv);
|
||||
|
||||
-- 8. 复合过滤索引(适配 repo + path 检索场景)
|
||||
-- 7. 复合索引
|
||||
CREATE INDEX IF NOT EXISTS idx_documents_repo_path
|
||||
ON public.documents (repo, path);
|
||||
|
||||
@ -1,34 +1,82 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
# -----------------------------------------------------------------------------
|
||||
# Linux installation (no repo, curl source)
|
||||
# -----------------------------------------------------------------------------
|
||||
if [[ "$OS" == "Linux" ]]; then
|
||||
echo "🐧 Installing on Linux ($OPENRESTY_ARCH)..."
|
||||
|
||||
CORES=$(sysctl -n hw.ncpu 2>/dev/null || nproc)
|
||||
# 1️⃣ 安装必要依赖
|
||||
echo "📦 Installing build dependencies..."
|
||||
sudo apt-get update -y
|
||||
sudo apt-get install -y build-essential libpcre3 libpcre3-dev zlib1g-dev libssl-dev perl curl tar
|
||||
|
||||
echo "Detected macOS. Installing GeoIP library into /opt/homebrew/geoip..."
|
||||
curl -LO https://github.com/maxmind/geoip-api-c/releases/download/v1.6.12/GeoIP-1.6.12.tar.gz
|
||||
# 2️⃣ 检查内存(若小于2GB则添加swap)
|
||||
MEM_TOTAL=$(awk '/MemTotal/ {print $2}' /proc/meminfo)
|
||||
if [ "$MEM_TOTAL" -lt 2097152 ]; then
|
||||
echo "⚠️ Memory less than 2GB, adding 1GB swap..."
|
||||
sudo fallocate -l 1G /swapfile || sudo dd if=/dev/zero of=/swapfile bs=1M count=1024
|
||||
sudo chmod 600 /swapfile
|
||||
sudo mkswap /swapfile
|
||||
sudo swapon /swapfile
|
||||
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab >/dev/null
|
||||
fi
|
||||
|
||||
tar zxvf GeoIP-1.6.12.tar.gz
|
||||
cd GeoIP-1.6.12
|
||||
./configure --prefix=/opt/homebrew/geoip
|
||||
make -j"${CORES}"
|
||||
sudo make install
|
||||
cd ..
|
||||
rm -rf GeoIP-1.6.12 GeoIP-1.6.12.tar.gz
|
||||
# 3️⃣ 下载源码
|
||||
VERSION=$(curl -s https://openresty.org/en/download.html | grep -Eo 'openresty-[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+' | head -n 1 | cut -d'-' -f2)
|
||||
URL="https://openresty.org/download/openresty-${VERSION}.tar.gz"
|
||||
|
||||
echo "Trying Homebrew build of OpenResty with GeoIP..."
|
||||
if ! CPPFLAGS="-I/opt/homebrew/geoip/include" \
|
||||
LDFLAGS="-L/opt/homebrew/geoip/lib" \
|
||||
brew install --build-from-source openresty/brew/openresty; then
|
||||
echo "Homebrew failed, falling back to manual source build..."
|
||||
curl -LO https://openresty.org/download/openresty-1.27.1.2.tar.gz
|
||||
tar zxvf openresty-1.27.1.2.tar.gz
|
||||
cd openresty-1.27.1.2
|
||||
echo "📦 Downloading OpenResty v${VERSION}..."
|
||||
curl -fSL "$URL" -o /tmp/openresty.tar.gz
|
||||
|
||||
echo "📂 Extracting..."
|
||||
cd /tmp
|
||||
tar -xzf openresty.tar.gz
|
||||
cd "openresty-${VERSION}"
|
||||
|
||||
# 4️⃣ 编译配置
|
||||
echo "⚙️ Configuring and building..."
|
||||
./configure \
|
||||
--prefix=/opt/homebrew/openresty \
|
||||
--with-http_geoip_module \
|
||||
--with-cc-opt="-I/opt/homebrew/geoip/include" \
|
||||
--with-ld-opt="-L/opt/homebrew/geoip/lib"
|
||||
make -j"${CORES}"
|
||||
--prefix=/usr/local/openresty \
|
||||
--with-http_ssl_module \
|
||||
--with-http_realip_module \
|
||||
--with-http_stub_status_module \
|
||||
--with-stream \
|
||||
--with-stream_ssl_module \
|
||||
--with-threads
|
||||
|
||||
# 5️⃣ 编译与安装
|
||||
make -j"${CORES}" || { echo "❌ Build failed, trying single-threaded build..."; make; }
|
||||
sudo make install
|
||||
cd ..
|
||||
rm -rf openresty-1.27.1.2 openresty-1.27.1.2.tar.gz
|
||||
|
||||
# 6️⃣ 校验安装结果
|
||||
if [ ! -x /usr/local/openresty/nginx/sbin/nginx ]; then
|
||||
echo "❌ OpenResty binary not found after install."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 7️⃣ systemd 服务
|
||||
echo "⚙️ Setting up systemd service..."
|
||||
sudo tee /lib/systemd/system/openresty.service >/dev/null <<'EOF'
|
||||
[Unit]
|
||||
Description=OpenResty Web Server
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=forking
|
||||
PIDFile=/usr/local/openresty/nginx/logs/nginx.pid
|
||||
ExecStart=/usr/local/openresty/nginx/sbin/nginx
|
||||
ExecReload=/usr/local/openresty/nginx/sbin/nginx -s reload
|
||||
ExecStop=/usr/local/openresty/nginx/sbin/nginx -s quit
|
||||
PrivateTmp=true
|
||||
LimitNOFILE=65535
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable --now openresty
|
||||
sudo systemctl status openresty --no-pager || true
|
||||
|
||||
echo "✅ OpenResty v${VERSION} installed successfully on Linux"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
@ -2,106 +2,129 @@
|
||||
set -euo pipefail
|
||||
|
||||
PG_MAJOR="${PG_MAJOR:-16}"
|
||||
ARCH=$(uname -m)
|
||||
DISTRO=$(lsb_release -cs)
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# 通用函数
|
||||
# -----------------------------------------------------------------------------
|
||||
fix-apt-keys() {
|
||||
echo "🔑 修复 GPG keyring 路径..."
|
||||
sudo mkdir -p /usr/share/keyrings /etc/apt/keyrings
|
||||
}
|
||||
|
||||
install-go() {
|
||||
local version="${GO_VERSION:-1.24.5}"
|
||||
local tarball="go${version}.linux-amd64.tar.gz"
|
||||
local arch_map
|
||||
case "$ARCH" in
|
||||
x86_64|amd64) arch_map="amd64" ;;
|
||||
arm64|aarch64) arch_map="arm64" ;;
|
||||
*) echo "❌ 不支持的架构 $ARCH"; exit 1 ;;
|
||||
esac
|
||||
|
||||
local tarball="go${version}.linux-${arch_map}.tar.gz"
|
||||
local url="https://go.dev/dl/${tarball}"
|
||||
|
||||
echo "=== 安装 Go ${version} (linux/amd64) ==="
|
||||
|
||||
# 1. 下载 Go 安装包
|
||||
echo "下载 ${url} ..."
|
||||
if ! wget -q --show-progress "$url" -O "$tarball"; then
|
||||
echo "❌ 无法下载 Go 安装包,请检查网络"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 2. 删除旧版本(如果有)
|
||||
if [ -d /usr/local/go ]; then
|
||||
echo "移除旧版本 Go..."
|
||||
sudo rm -rf /usr/local/go
|
||||
fi
|
||||
|
||||
# 3. 解压到 /usr/local
|
||||
echo "解压到 /usr/local ..."
|
||||
echo "=== 安装 Go ${version} (${arch_map}) ==="
|
||||
wget -q --show-progress "$url" -O "$tarball"
|
||||
sudo rm -rf /usr/local/go
|
||||
sudo tar -C /usr/local -xzf "$tarball"
|
||||
|
||||
# 4. 配置环境变量(全局)
|
||||
echo "配置全局 PATH ..."
|
||||
echo 'export PATH=$PATH:/usr/local/go/bin' | sudo tee /etc/profile.d/go.sh >/dev/null
|
||||
sudo chmod +x /etc/profile.d/go.sh
|
||||
|
||||
# 5. 立即生效(当前终端)
|
||||
export PATH=$PATH:/usr/local/go/bin
|
||||
|
||||
# 6. 验证安装
|
||||
if go version >/dev/null 2>&1; then
|
||||
echo "✅ Go 安装成功: $(go version)"
|
||||
else
|
||||
echo "❌ Go 安装失败,请检查"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 清理 tar.gz
|
||||
go version
|
||||
rm -f "$tarball"
|
||||
}
|
||||
|
||||
install-nodejs() {
|
||||
set -euo pipefail
|
||||
# 选择 Node 主版本,默认 22(LTS)
|
||||
echo "=== 安装 Node.js(通用二进制) ==="
|
||||
|
||||
local NODE_MAJOR="${NODE_MAJOR:-22}"
|
||||
local ARCH
|
||||
ARCH=$(uname -m)
|
||||
local PLATFORM="linux"
|
||||
local NODE_ARCH
|
||||
|
||||
echo "=== 安装 Node.js ${NODE_MAJOR}.x(Ubuntu 22.04)==="
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y ca-certificates curl gnupg
|
||||
case "$ARCH" in
|
||||
x86_64|amd64) NODE_ARCH="x64" ;;
|
||||
aarch64|arm64) NODE_ARCH="arm64" ;;
|
||||
*)
|
||||
echo "❌ 不支持的架构: $ARCH"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# NodeSource 官方仓库(更稳妥的 GPG 方式)
|
||||
sudo install -d -m 0755 /etc/apt/keyrings
|
||||
curl -fsSL --socks5-hostname 127.0.0.1:1080 https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | sudo gpg --batch --yes --dearmor -o /etc/apt/keyrings/nodesource.gpg || true
|
||||
curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | sudo gpg --batch --yes --dearmor -o /etc/apt/keyrings/nodesource.gpg || true
|
||||
gpg --keyserver keyserver.ubuntu.com --recv-keys 2F59B5F99B1BE0B4
|
||||
gpg --export --armor 2F59B5F99B1BE0B4 | sudo tee /etc/apt/trusted.gpg.d/missing-key.gpg
|
||||
# 从 Node 官方 API 获取最新版本号
|
||||
echo "📡 检测 Node.js ${NODE_MAJOR}.x 最新版本..."
|
||||
local VERSION
|
||||
VERSION=$(curl -sL "https://nodejs.org/dist/index.json" | grep -Eo "\"v${NODE_MAJOR}\.[0-9]+\.[0-9]+\"" | head -n1 | tr -d '"')
|
||||
if [ -z "$VERSION" ]; then
|
||||
echo "❌ 无法获取 Node ${NODE_MAJOR}.x 最新版本号"
|
||||
exit 1
|
||||
fi
|
||||
echo "📦 准备安装 Node.js ${VERSION} (${PLATFORM}-${NODE_ARCH})"
|
||||
|
||||
echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_${NODE_MAJOR}.x nodistro main" \
|
||||
| sudo tee /etc/apt/sources.list.d/nodesource.list >/dev/null
|
||||
local TARBALL="node-${VERSION}-${PLATFORM}-${NODE_ARCH}.tar.xz"
|
||||
local URL="https://nodejs.org/dist/${VERSION}/${TARBALL}"
|
||||
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y nodejs
|
||||
# 下载与安装
|
||||
curl -fSL "$URL" -o "/tmp/${TARBALL}"
|
||||
local PREFIX="/usr/local/node-${VERSION}"
|
||||
sudo rm -rf "$PREFIX"
|
||||
sudo mkdir -p "$PREFIX"
|
||||
sudo tar -xJf "/tmp/${TARBALL}" -C "$PREFIX" --strip-components=1
|
||||
rm -f "/tmp/${TARBALL}"
|
||||
|
||||
# 启用 Corepack,激活 Yarn(Berry)
|
||||
sudo corepack enable || true
|
||||
# 链接到系统路径
|
||||
sudo ln -sf "${PREFIX}/bin/node" /usr/local/bin/node
|
||||
sudo ln -sf "${PREFIX}/bin/npm" /usr/local/bin/npm
|
||||
sudo ln -sf "${PREFIX}/bin/npx" /usr/local/bin/npx
|
||||
sudo ln -sf "${PREFIX}/bin/corepack" /usr/local/bin/corepack
|
||||
|
||||
# 启用 Corepack(Yarn、pnpm)
|
||||
corepack enable || true
|
||||
corepack prepare yarn@stable --activate || true
|
||||
|
||||
# 版本校验
|
||||
local node_v
|
||||
node_v="$(node -v 2>/dev/null || true)"
|
||||
if [ -z "$node_v" ]; then
|
||||
echo "❌ Node 未安装成功"
|
||||
exit 1
|
||||
fi
|
||||
echo "Node: $node_v"
|
||||
echo "Yarn: $(yarn -v 2>/dev/null || echo '未启用(可忽略)')"
|
||||
|
||||
# 要求 >= 20
|
||||
local major="${node_v#v}"
|
||||
major="${major%%.*}"
|
||||
if [ "$major" -lt 20 ]; then
|
||||
echo "❌ Node 主版本过低($node_v),请设置 NODE_MAJOR=20 或以上后重试"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "✅ Node.js 安装完成,满足 >=20"
|
||||
echo "✅ Node.js 安装完成: $(node -v)"
|
||||
echo " npm: $(npm -v)"
|
||||
echo " Yarn: $(yarn -v || echo '未启用')"
|
||||
}
|
||||
|
||||
install-postgresql() {
|
||||
echo "=== 安装 PostgreSQL ${PG_MAJOR} ==="
|
||||
sudo apt-get update
|
||||
|
||||
# 安装依赖
|
||||
sudo apt-get update -y
|
||||
sudo apt-get install -y wget curl gnupg lsb-release ca-certificates
|
||||
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 2F59B5F99B1BE0B4
|
||||
echo "deb [signed-by=/usr/share/keyrings/postgresql.gpg] http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" | sudo tee /etc/apt/sources.list.d/pgdg.list
|
||||
sudo apt-get install -y "postgresql-${PG_MAJOR}" "postgresql-client-${PG_MAJOR}" "postgresql-contrib-${PG_MAJOR}" "postgresql-server-dev-${PG_MAJOR}"
|
||||
|
||||
# 修复 GPG key 路径
|
||||
sudo mkdir -p /usr/share/keyrings /etc/apt/keyrings
|
||||
|
||||
# 添加 PostgreSQL 官方仓库
|
||||
if [ ! -f /usr/share/keyrings/postgresql.gpg ]; then
|
||||
echo "📦 添加 PostgreSQL 官方仓库..."
|
||||
curl -fsSL https://www.postgresql.org/media/keys/ACCC4CF8.asc \
|
||||
| sudo gpg --dearmor -o /usr/share/keyrings/postgresql.gpg
|
||||
fi
|
||||
|
||||
local DISTRO
|
||||
DISTRO=$(lsb_release -cs)
|
||||
echo "deb [signed-by=/usr/share/keyrings/postgresql.gpg] \
|
||||
http://apt.postgresql.org/pub/repos/apt ${DISTRO}-pgdg main" \
|
||||
| sudo tee /etc/apt/sources.list.d/pgdg.list >/dev/null
|
||||
|
||||
# 安装 PostgreSQL
|
||||
sudo apt-get update -y
|
||||
sudo apt-get install -y \
|
||||
"postgresql-${PG_MAJOR}" \
|
||||
"postgresql-client-${PG_MAJOR}" \
|
||||
"postgresql-contrib-${PG_MAJOR}" \
|
||||
"postgresql-server-dev-${PG_MAJOR}"
|
||||
|
||||
# 启动并设置开机自启
|
||||
sudo systemctl enable --now postgresql
|
||||
|
||||
# 显示版本与状态
|
||||
echo "✅ PostgreSQL 安装完成: $(psql --version)"
|
||||
sudo -u postgres psql -c "SELECT version();" || true
|
||||
}
|
||||
|
||||
install-redis() {
|
||||
@ -116,55 +139,44 @@ install-pgvector() {
|
||||
sudo apt-get install -y git make gcc
|
||||
tmp_dir=$(mktemp -d)
|
||||
cd "$tmp_dir"
|
||||
git clone git@github.com:svc-design/pgvector.git
|
||||
git clone https://github.com/pgvector/pgvector.git
|
||||
cd pgvector
|
||||
make && sudo make install
|
||||
cd /
|
||||
rm -rf "$tmp_dir"
|
||||
}
|
||||
|
||||
install-zhparser() {
|
||||
echo "=== 安装 scws v1.2.3 + zhparser ==="
|
||||
sudo apt-get install -y automake autoconf libtool pkg-config
|
||||
install-pgjieba() {
|
||||
echo "=== 安装 pg_jieba (替代 zhparser + scws) ==="
|
||||
sudo apt-get update -y
|
||||
sudo apt-get install -y cmake g++ git postgresql-server-dev-${PG_MAJOR}
|
||||
|
||||
# 编译安装 scws v1.2.3
|
||||
tmp_dir=$(mktemp -d)
|
||||
cd "$tmp_dir"
|
||||
git clone git@github.com:svc-design/scws.git
|
||||
cd scws
|
||||
|
||||
# 修掉 automake 不兼容的注释
|
||||
sed -i '/^[[:space:]]*#/d' Makefile.am || true
|
||||
# 克隆仓库
|
||||
git clone https://github.com/jaiminpan/pg_jieba.git
|
||||
cd pg_jieba
|
||||
|
||||
# 生成 configure
|
||||
if [ ! -f configure ]; then
|
||||
if [ -x ./autogen.sh ]; then
|
||||
./autogen.sh
|
||||
else
|
||||
autoreconf -fi
|
||||
fi
|
||||
fi
|
||||
# 创建构建目录
|
||||
mkdir build && cd build
|
||||
cmake -DPostgreSQL_TYPE_INCLUDE_DIR=/usr/include/postgresql/${PG_MAJOR}/server ..
|
||||
make -j"$(nproc)"
|
||||
sudo make install
|
||||
|
||||
./configure --prefix=/usr
|
||||
make -j"$(nproc)" && sudo make install
|
||||
cd /
|
||||
rm -rf "$tmp_dir"
|
||||
|
||||
# 编译安装 zhparser
|
||||
tmp_dir=$(mktemp -d)
|
||||
cd "$tmp_dir"
|
||||
git clone git@github.com:svc-design/zhparser.git
|
||||
cd zhparser
|
||||
pg_config_path="$(command -v pg_config || echo "/usr/lib/postgresql/${PG_MAJOR}/bin/pg_config")"
|
||||
make SCWS_HOME=/usr PG_CONFIG="${pg_config_path}"
|
||||
sudo make install SCWS_HOME=/usr PG_CONFIG="${pg_config_path}"
|
||||
cd /
|
||||
rm -rf "$tmp_dir"
|
||||
echo "✅ pg_jieba 安装完成"
|
||||
echo "可在 PostgreSQL 中启用:CREATE EXTENSION pg_jieba;"
|
||||
}
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# 调度入口
|
||||
# -----------------------------------------------------------------------------
|
||||
if declare -f "$1" > /dev/null; then
|
||||
"$1"
|
||||
else
|
||||
echo "用法: $0 {install-postgresql|install-redis|install-pgvector|install-zhparser}"
|
||||
echo "用法: $0 {install-go|install-nodejs|install-postgresql|install-redis|install-pgvector|install-pgjieba}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
Loading…
Reference in New Issue
Block a user