docs(deploy): README 全流程本地部署方案 + scripts/dev-up.sh 一键启动(PG→llama.cpp embedding→cyrene),路径固定 ~/apps 与 ~/.models,勿用 /tmp
CI / Backend (build / vet / test / cross-compile) (push) Has been cancelled
CI / Frontend (tsc + vite build) (push) Has been cancelled

This commit is contained in:
Aska committed 2026-09-06 11:39:59 +08:00
1 parent 7c662511ba
commit 0c93bb4497
2 files changed
+110 -10

No files matched your search

+50 -10
View File
@@ -18,14 +18,22 @@
---
## 本地部署(用户侧)
## 本地部署(用户侧 · 全流程)
### 1. 前置
- Go 1.26、Node 22(前端构建用)、Docker(**可选**,用于 PostgreSQL + pgvector / 本地 embedding)。
### 0. 前置
- Go 1.26、Node 22(前端构建用)、Docker(用于 PostgreSQL + pgvector;不用 PG 可仅用 SQLite)。
### 1. 一键启动(最快,推荐)
```bash
bash scripts/dev-up.sh
# 依次拉起:PG+pgvector → llama.cpp embedding(Qwen3) → 前端 build → cyrene
# 访问 http://localhost:8080(按 .env 的 PORT)
```
> `scripts/dev-up.sh` 约定:llama.cpp 放 `~/apps/llama.cpp/`、GGUF 放 `~/.models/`、cyrene 二进制 `~/apps/cyrene/cyrene`。已运行的服务会自动跳过。
### 2. 配置 `.env`(复制 `.env.example`)
```bash
# 认证
# 认证(JWT_SECRET 必填 ≥32)
JWT_SECRET=<≥32 字符随机串>
ADMIN_USERNAME=admin
ADMIN_PASSWORD=<你的密码>
@@ -37,24 +45,56 @@ ANTHROPIC_API_KEY=<key>
ANTHROPIC_MODEL=deepseek-chat
# 或 OpenAI 兼容:LLM_PROVIDER=openai + LLM_BASE_URL/API_KEY/MODEL
# 数据库(可选增强:PG + pgvector 向量检索)
# 数据库(可选增强:PG + pgvector 向量检索;不配则用 SQLite)
DB_PG_URL=postgres://cyrene:cyrene_pass@localhost:5432/cyrene_ai?sslmode=disable
# 记忆嵌入(真语义;EMBEDDING_API_URL 必须是【完整 /v1/embeddings 端点】,不是 base)
EMBEDDING_API_URL=http://localhost:11434/v1/embeddings
EMBEDDING_MODEL=Qwen3-Embedding-0.6B
```
### 3. 可选依赖(Docker;PG+pgvector 必需可加,embedding 可选)
### 3. 数据库(PG + pgvector,Docker)
```bash
docker compose -f docker-compose.dev.yml up -d # PG + pgvector
docker compose -f docker-compose.dev.yml --profile embedding up -d embedding # 可选:本地 embedding(Ollama)
# 若用 embedding:docker exec -it cyrene-embedding ollama pull <model>
docker compose -f docker-compose.dev.yml up -d pg
# 首次:vector 扩展由应用自动 CREATE(本地 cyrene 用户为 superuser)
```
> 不用 PG 可跳过;SQLite 默认即用。
### 4. 构建并启动(单二进制,go:embed 前端)
### 4. 本地 embedding(llama.cpp + Qwen3 GGUF,走 Vulkan/GPU)
```bash
# 一次准备(llama.cpp 放 ~/apps/llama.cpp/,模型放 ~/.models/;勿用 /tmp)
mkdir -p ~/apps/llama.cpp ~/.models
# llama.cpp release(Vulkan)解压到 ~/apps/llama.cpp/
# Qwen3-Embedding-0.6B-Q8_0.gguf(~639MB,ModelScope 下载)→ ~/.models/
chmod 644 ~/.models/Qwen3-Embedding-0.6B-Q8_0.gguf
# 启动
~/apps/llama.cpp/llama-server -m ~/.models/Qwen3-Embedding-0.6B-Q8_0.gguf \
--embedding -ngl 99 --host 127.0.0.1 --port 11434 &
```
> **模型来源**:HuggingFace 国内不可访问,请从 **ModelScope(魔搭)** 下载 `Qwen3-Embedding-0.6B-Q8_0.gguf`。llama.cpp 只认 **GGUF**(`model.safetensors` 是 transformers/HF 用的,不能直接喂)。
### 5. 构建并启动(单二进制,go:embed 前端)
```bash
cd frontend/web && npm ci && npm run build && cd ../.. # 产 dist(含拷到 internal/webui/dist)
go build -ldflags="-s -w" -trimpath -o cyrene ./cmd/cyrene/
./cyrene # 访问 http://localhost:8080(按 .env 的 PORT)
```
### 6. 服务端口 / 路径速查
| 服务 | 地址 / 路径 | 说明 |
|------|------------|------|
| Cyrene 网关 | http://localhost:8080(`.env:PORT`) | SPA + REST/WS + 面板 `/admin` |
| PG + pgvector | `localhost:5432`(docker `cyrene-pg`) | 向量索引在 `cyrene_ai` |
| llama.cpp embedding | `http://localhost:11434/v1/embeddings` | Qwen3,Vulkan |
### 7. 注意事项
- **勿用 `/tmp` 放二进制/模型**(tmpfs 在内存里,堆多了会炸);一律 `~/apps/`、`~/.models/`。
- `EMBEDDING_API_URL` **必须是完整 `/v1/embeddings`**(不是 base),否则 404。
- **切换 embedding 模型会改维度**(Qwen3=1024,n-gram=256)→ 换模型前清一次向量表:`docker exec cyrene-pg psql -U cyrene -d cyrene_ai -c "TRUNCATE vec_items;"`(懒创建的真向量表)。
- LLM 用 anthropic 协议时填 `ANTHROPIC_*`;用 openai 兼容时填 `LLM_*`。`LLM_PROVIDER` 二选一。
---
## Embedding 模型推荐
+60
View File
@@ -0,0 +1,60 @@
#!/usr/bin/env bash
# Cyrene v2 本地一键开发启动:PG+pgvector → llama.cpp embedding → 前端 build → cyrene
# 用法:bash scripts/dev-up.sh (在仓库根目录;需 docker + go + node)
set -euo pipefail
REPO="$(cd "$(dirname "$0")/.." && pwd)"
MODEL_DIR="$HOME/.models"
LLAMA_DIR="$HOME/apps/llama.cpp"
APP_NAME="cyrene"
APP_BIN="$HOME/apps/cyrene/$APP_NAME"
EMB_MODEL="$MODEL_DIR/Qwen3-Embedding-0.6B-Q8_0.gguf"
EMB_PORT=11434
GW_PORT=10080
cd "$REPO"
echo "==> [1/4] PostgreSQL + pgvector (docker)"
if command -v docker >/dev/null 2>&1; then
docker compose -f docker-compose.dev.yml up -d pg || echo " (docker compose up pg 失败,忽略继续——若未用 PG 可跳过)"
else
echo " (未检测到 docker;若用 SQLite 默认可不启动 PG)"
fi
echo "==> [2/4] llama.cpp embedding (Qwen3-Embedding,Vulkan)"
if [ -x "$LLAMA_DIR/llama-server" ] && [ -f "$EMB_MODEL" ]; then
# 已在跑则跳过
if ! curl -s --max-time 2 "http://127.0.0.1:$EMB_PORT/health" >/dev/null 2>&1; then
(cd "$LLAMA_DIR" && nohup ./llama-server -m "$EMB_MODEL" --embedding -ngl 99 --host 127.0.0.1 --port "$EMB_PORT" > "$HOME/cy-emb.log" 2>&1 &)
echo " llama-server 已启动: http://127.0.0.1:$EMB_PORT"
else
echo " llama-server 已在运行 (: $EMB_PORT),跳过"
fi
else
echo " (未找到 $LLAMA_DIR/llama-server 或模型 $EMB_MODEL;跳过。"
echo " llama.cpp 放 ~/apps/llama.cpp,GGUF 放 ~/.models/)"
fi
echo "==> [3/4] 前端构建 (go:embed 需要 dist)"
if [ -d frontend/web ]; then
(cd frontend/web && npm ci >/dev/null 2>&1 && npm run build >/dev/null 2>&1) || echo " (前端 build 跳过/失败——若已存在 dist 可忽略)"
fi
echo "==> [4/4] 构建并启动 cyrene"
if [ ! -f "$APP_BIN" ]; then
mkdir -p "$HOME/apps/cyrene"
echo " go build -> $APP_BIN"
go build -ldflags="-s -w" -trimpath -o "$APP_BIN" ./cmd/cyrene
fi
if ! curl -s --max-time 2 "http://127.0.0.1:$GW_PORT/api/v1/health" >/dev/null 2>&1; then
(cd "$REPO" && nohup "$APP_BIN" > "$HOME/cy.log" 2>&1 &)
echo " cyrene 已启动: http://localhost:$GW_PORT (日志 $HOME/cy.log)"
else
echo " cyrene 已在运行 (: $GW_PORT),跳过"
fi
echo
echo "完成。访问 http://localhost:$GW_PORT (.env 的 PORT 覆盖此值)"
echo " · LLM: .env 的 LLM_PROVIDER / ANTHROPIC_* 或 LLM_*"
echo " · 向量: EMBEDDING_API_URL=http://127.0.0.1:$EMB_PORT/v1/embeddings EMBEDDING_MODEL=Qwen3-Embedding-0.6B"
echo " · 停止: pkill -f llama-server ; pkill -f $APP_NAME"