From 1d9c14300d7e184b07cfe7c68e04e9412f7db5ce Mon Sep 17 00:00:00 2001 From: Aska Date: Sun, 6 Sep 2026 10:39:27 +0800 Subject: [PATCH] =?UTF-8?q?fix(db):=20Open=20=E8=87=AA=E5=8A=A8=E5=88=9B?= =?UTF-8?q?=E5=BB=BA=E7=88=B6=E7=9B=AE=E5=BD=95=EF=BC=88=E8=87=AA=E5=AE=9A?= =?UTF-8?q?=E4=B9=89=20DATA=5FDIR=20=E9=A6=96=E5=90=AF=E4=B8=8D=E6=8A=A5?= =?UTF-8?q?=E9=94=99=EF=BC=89=EF=BC=9Badd=20docker-compose.dev.yml?= =?UTF-8?q?=EF=BC=88PG+pgvector=20=E5=BF=85=E9=9C=80=20+=20Ollama=20embedd?= =?UTF-8?q?ing=20=E5=8F=AF=E9=80=89=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docker-compose.dev.yml | 47 ++++++++++++++++++++++++++++++++++++++++++ internal/db/db.go | 12 +++++++++++ 2 files changed, 59 insertions(+) create mode 100644 docker-compose.dev.yml diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml new file mode 100644 index 0000000..dbc3749 --- /dev/null +++ b/docker-compose.dev.yml @@ -0,0 +1,47 @@ +# Cyrene v2 本地开发依赖(docker compose) +# 用法: +# 1) 先停掉之前手动起的容器,避免端口冲突: +# docker rm -f cyrene-pg # 若有旧的手动容器 +# 2) 启动: +# docker compose -f docker-compose.dev.yml up -d +# 3) 验证 pgvector: +# docker exec cyrene-pg psql -U cyrene -d cyrene_ai \ +# -c "CREATE EXTENSION IF NOT EXISTS vector; SELECT extversion FROM pg_extension WHERE extname='vector';" +# +# 注:SQLite 为默认内嵌库(文件,不需要容器);PG+pgvector 为可选增强(向量检索)。 +# 服务 `embedding`(Ollama)为可选:用于真语义嵌入(EMBEDDING_API_URL),不需要就注释掉/不加。 + +services: + # 主数据库:PostgreSQL 16 + pgvector(向量索引走这里) + pg: + image: pgvector/pgvector:pg16 + container_name: cyrene-pg + environment: + POSTGRES_USER: cyrene # 该用户会在镜像里被创建为 superuser(本地开发方便建 vector 扩展) + POSTGRES_PASSWORD: cyrene_pass + POSTGRES_DB: cyrene_ai + ports: + - "5432:5432" + volumes: + - pgdata:/var/lib/postgresql/data + healthcheck: + test: ["CMD-SHELL", "pg_isready -U cyrene -d cyrene_ai"] + interval: 5s + timeout: 3s + retries: 12 + + # 可选:本地 embedding(真语义向量)。用 Ollama 跑 bge-m3。 + # 启用后需拉模型:docker exec -it cyrene-embedding ollama pull bge-m3 + # 并让 .env 指到它:EMBEDDING_API_URL=http://localhost:11434/v1, EMBEDDING_MODEL=bge-m3 + embedding: + image: ollama/ollama:latest + container_name: cyrene-embedding + profiles: ["embedding"] # 默认不启动;需要时 `docker compose --profile embedding up -d` + ports: + - "11434:11434" + volumes: + - ollama:/root/.ollama + +volumes: + pgdata: + ollama: diff --git a/internal/db/db.go b/internal/db/db.go index 3f0efa9..6ff8ea6 100644 --- a/internal/db/db.go +++ b/internal/db/db.go @@ -22,6 +22,8 @@ import ( "fmt" "io" "log/slog" + "os" + "path/filepath" "strings" _ "modernc.org/sqlite" // pure-Go SQLite driver, registers driver name "sqlite" @@ -66,6 +68,16 @@ func Open(ctx context.Context, path string, log *slog.Logger) (*sql.DB, error) { } log = discardLogger(log) + // Ensure the parent directory exists for file-backed databases so a custom + // DATA_DIR (e.g. ./data) works on first run without a pre-made directory. + if !isMemory(path) { + if dir := filepath.Dir(path); dir != "" && dir != "." { + if err := os.MkdirAll(dir, 0o755); err != nil { + return nil, fmt.Errorf("db: create dir %q: %w", dir, err) + } + } + } + db, err := sql.Open("sqlite", buildDSN(path)) if err != nil { return nil, fmt.Errorf("db: open %q: %w", path, err)