[实战] RAG 知识库:Windows 下 Docker 部署 PostgreSQL + pgvector 避坑指南

在开发 RAG(检索增强生成)应用时,需要向量数据库来存储 Embedding 数据。对于个人开发者,PostgreSQL + pgvector 是比 Milvus 更轻量、更友好的选择。

但在 Windows 环境下安装 pgvector 插件极易踩坑(涉及 C++ 编译)。本文记录最稳健的 Docker 部署方案。

1. 为什么不用本地安装?

如果你尝试在 Windows 本地安装的 PostgreSQL 中开启 vector 插件,可能会遇到如下报错:

ERROR: extension "vector" is not available`
`DETAIL: Could not open extension control file ... vector.control

原因:Windows 版 PG 不自带该插件,手动编译需要 Visual Studio C++ 环境,难度极高。
解法:直接使用官方封装好的 Docker 镜像。

2. 目录结构规划

为了不影响现有的其他容器(如 Redis),建议独立目录管理。

E:\docker\
├─ redis\               # 现有的其他服务
└─ rag-pgvector\        # 新建文件夹,专用于向量库
   ├─ docker-compose.yml
   └─ pgdata			# 目前和下列均为可选(初始化数据库)
   └─ initdb\			
      └─ 01_init.sql	

3. 配置文件 (docker-compose.yml)

在 rag-db 目录下新建 docker-compose.yml:

version: '3'
services:
  db:
    # 🔥 核心:必须使用带插件的镜像,不能用普通的 postgres:latest
    image: pgvector/pgvector:pg16
    container_name: pgvector_db
    restart: always
    environment:
      POSTGRES_USER的名字: root         # 或 postgres
      POSTGRES_PASSWORD: 123456   # 你的密码
      POSTGRES_DB: xinjing_rag    # 初始化创建的数据库名,不写默认为POSTGRES_USER的名字
    ports:
      - "5432:5432"               # 宿主机端口:容器端口
    volumes:
      - ./pgdata:/var/lib/postgresql/data # 数据持久化挂载(没有pgdata会新建)
      - ./pgvector_init.sql:/docker-entrypoint-initdb.d/pgvector_init.sql # 数据初始化,可选参数,docker-entrypoint-initdb.d为固定写法,pgvector_init.sql自定义的sql文件

注意:

  • 避免端口冲突

启动前请检查端口 5432 是否被本地 PG 占用 (netstat -ano | findstr :5432)。如果冲突,修改左侧端口为 - "5433:5432"。

  • 避免容器名冲突

路径区别

写法含义实际路径
./pgdata相对路径,当前目录下的 pgdatae:\docker\rag-pgvector\pgdata
pgdata命名卷,Docker 管理的卷C:\ProgramData\Docker\volumes\pgdata\_data

含义:

  • 宿主机:

    e:\docker\rag-pgvector\pgdata
    
  • 容器内:

    /var/lib/postgresql/data
    
  • 两者同步映射

推荐使用

./pgdata,因为数据可见、易管理。

部分是否可改说明
./01_init.sql✅ 可改宿主机文件路径和名称随意
/docker-entrypoint-initdb.d/❌ 不可改PostgreSQL 镜像固定路径
01_init.sql✅ 可改容器内文件名可改(建议用数字前缀控制顺序)
部分含义
./01_init.sql宿主机文件:e:\docker\rag-pgvector\01_init.sql
:映射符号
/docker-entrypoint-initdb.d/01_init.sql容器内路径:PostgreSQL 初始化脚本目录

PostgreSQL 官方镜像特性:

  • 容器首次启动时,自动执行**/docker-entrypoint-initdb.d/**目录下的.sql或.sh文件
  • 按文件名字母顺序执行(01_前缀确保执行顺序)
  • 只在数据库初始化时执行一次

执行时机

# 首次启动 → 执行 01_init.sql
docker-compose up -d

# 再次启动 → 不执行(数据已存在)
docker-compose restart

# 重新初始化 → 删除数据后启动
docker-compose down
rmdir /s pgdata
docker-compose up -d  # 再次执行初始化脚本

4. 启动与初始化

步骤一:启动容器

在当前目录打开命令行(PowerShell),执行:

docker-compose up -d

步骤二:开启插件 (关键!)

连接数据库(推荐 DBeaver),执行一次以下 SQL,否则向量类型无法使用:

CREATE EXTENSION IF NOT EXISTS vector;

步骤三:验证

创建测试表,不报错即成功:

CREATE TABLE test_emb (
    id bigserial PRIMARY KEY,
    vec vector(1024) -- 对应阿里千问v3模型维度
);

修改数据库名(无数据方式)

1. 停止容器

在命令行(PowerShell)里输入:

docker-compose down
2. ⚠️ 关键步骤:删除旧数据

去你的文件夹 E:\docker\rag-db 下,找到那个叫 pgdata 的文件夹。
直接把它删掉!
(注意:这一步会清空你这个数据库里所有的数据。因为你是刚开始做,所以应该没关系。)

3. 修改 YML 文件

打开 docker-compose.yml,修改数据库名字:

environment:
  POSTGRES_USER: root
  POSTGRES_PASSWORD: 123456
  POSTGRES_DB: rag_db   <-- 改成你想要的新名字

保存文件。

4. 重新启动

回到命令行输入:

docker-compose up -d

5. 常见问题 (FAQ)

Q: 我想修改数据库名 (POSTGRES_DB) 或密码,直接改 yml 重启没生效?
A: Docker 仅在首次创建时读取环境变量。
解决方案(万能三连):

  1. docker-compose down (停止容器)
  2. 删除 pgdata 文件夹 (注意:数据会丢失,仅限开发期)
  3. docker-compose up -d (重新启动,生成新环境)

Q: 为什么不把初始化 SQL 写在 yml 里自动执行?
A: 可以通过挂载 /docker-entrypoint-initdb.d/ 实现,但对于初学者,手动执行 CREATE EXTENSION 更直观,便于确认插件状态。

Q:两个文件夹都要yml配置文件,启动两个是启动两个docker吗?

A:不是的。放在两个文件夹里,不是“启动两个 Docker”。

你电脑上只有一套 Docker(Docker Desktop/Engine)。不同文件夹只是代表 两套 docker-compose 项目(两个“编排工程”),它们都会在同一个 Docker 里创建各自的容器、网络、数据卷。需要哪个启动哪个。


总结:Windows 开发 RAG,千万别折腾本地编译,Docker 一键部署 pgvector/pgvector 才是正道。

更多推荐