记录一次从零搭建向量数据库环境的实战经历,以及那些让人抓狂的坑
背景
最近需要测试 pgvector 扩展,用于存储和检索向量数据(比如 AI 嵌入)。为了不影响本地开发环境,我决定使用 Docker Desktop for Windows 来快速部署一个独立的 PostgreSQL 实例。
本以为一个 docker-compose up -d 就能搞定,结果却接连踩了 端口冲突 和 认证失败 两个大坑。本文将完整记录整个流程,希望能帮你避开这些弯路。
环境准备
- Windows 10 / 11(已安装 Docker Desktop,并启用 WSL 2 后端)
- 终端:PowerShell 或 CMD
- 客户端工具:Navicat 17(或其他 PostgreSQL 客户端)
第一步:编写 docker-compose.yml
我选择使用 pgvector/pgvector 官方镜像,它基于 PostgreSQL 官方镜像并预装了 pgvector 扩展。为了数据持久化,采用 Docker 命名卷。
yaml
# docker-compose.yml
version: '3.8'
services:
db:
image: pgvector/pgvector:pg17 # 固定版本,避免 latest 漂移
container_name: pgvector-db
environment:
POSTGRES_PASSWORD: your_secure_password # 请替换为强密码
POSTGRES_DB: my_app_db # 默认创建的数据库
# POSTGRES_USER: admin # 注意:一旦指定,默认 postgres 用户将不再创建
ports:
- "5432:5432" # 宿主机端口:容器端口
volumes:
- pgdata:/var/lib/postgresql/data # 命名卷持久化
restart: unless-stopped
volumes:
pgdata:
💡 关键点 :如果设置了
POSTGRES_USER,则默认的postgres超级用户会被覆盖,后续所有连接都要用自定义用户名。
第二步:启动容器
在 docker-compose.yml 所在目录执行:
docker-compose up -d
首次运行会自动拉取镜像(约 500 MB),稍等片刻即可。
检查容器状态:
docker ps
如果看到 pgvector-db 状态为 Up,说明启动成功。
第三步:激活 pgvector 扩展
虽然镜像已预装扩展,但需要在每个数据库内手动启用。
bash
docker exec -it pgvector-db psql -U admin -d my_app_db -c "CREATE EXTENSION IF NOT EXISTS vector;"
(如果你的用户名是 postgres,请相应调整 -U 参数)
此时扩展已激活,可以测试:
arduino
SELECT vector_dimension('[1,2,3]'::vector);
-- 返回 3
第四步:Navicat 连接测试(踩坑开始!)
一切就绪,打开 Navicat 新建 PostgreSQL 连接:
- 主机:127.0.0.1
- 端口:5432
- 用户名:admin(或 postgres)
- 密码:你设置的密码
结果 :测试失败,报错 Password 认证失败。
明明刚才用 docker exec 可以正常登录,为何 Navicat 连不上?
坑一:本机旧 PostgreSQL 抢占 5432 端口
使用 netstat 排查:
netstat -ano | findstr :5432
输出显示:
yaml
TCP 0.0.0.0:5432 0.0.0.0:0 LISTENING 28364
TCP 0.0.0.0:5432 0.0.0:0 LISTENING 9276
两个进程同时监听 5432 端口!其中一个是我本机之前安装的 PostgreSQL 服务,另一个是 Docker 映射的进程。
网络请求可能会被路由到错误的进程,导致认证混乱(即使 Docker 容器是正常运行的)。
解决方法:
- 方案 A(彻底) :卸载本机 PostgreSQL(控制面板 → 程序和功能 → 卸载),释放端口。
- 方案 B(兼容) :修改 Docker 映射端口为
5433:5432,然后 Navicat 连接端口改为5433。
我选择了方案 A,因为用 Docker 后就不再需要本机 PG 了。
卸载后重启,再次 netstat -ano | findstr :5432,只剩一个进程(Docker 的),端口干净了。
坑二:Navicat 认证方式与 PostgreSQL 17 不兼容
即便端口冲突解决了,Navicat 依然报密码错误。这是因为 PostgreSQL 17 默认使用 scram-sha-256 密码加密 ,而某些旧版或配置不当的客户端(包括 Navicat 17 的某些设置)可能尝试用 md5 方式认证。
解决办法 :在 Navicat 连接设置中,切换到 "高级" 选项卡,将 "认证方式" 从默认改为 scram-sha-256(或者如果有 md5 选项,也可以尝试切换)。保存后重新测试连接,即告成功。
最终验证
连接成功后,执行一条向量函数:
arduino
SELECT vector_dimension('[0.1, 0.2, 0.3]'::vector);
返回 3,说明一切正常。
总结与建议
- 端口冲突是最隐蔽的问题 :容器虽然显示
Up,但宿主机端口可能已被其他程序占用,导致连接异常。遇到认证失败时,先检查端口占用情况。 - 明确用户名 :如果自定义了
POSTGRES_USER,则默认postgres不存在,后续所有操作都要用新用户名。 - 认证方式 :新版 PostgreSQL 使用
scram-sha-256,确保客户端支持或手动调整。 - 固定镜像标签 :使用
pg17而非latest,避免未来大版本升级导致不兼容。
如果你也在 Windows 上用 Docker 部署 pgvector,希望本文能帮你省下几小时的排查时间。欢迎留言交流!
扩展阅读 :pgvector 官方文档 | Docker Compose 官方文档