[实战] RAG 知识库:Windows 下 Docker 部署 PostgreSQL + pgvector 避坑指南
[实战] 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 | 相对路径,当前目录下的 pgdata | e:\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 仅在首次创建时读取环境变量。
解决方案(万能三连):
docker-compose down(停止容器)- 删除
pgdata文件夹 (注意:数据会丢失,仅限开发期) 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 才是正道。
更多推荐

所有评论(0)