Docker 部署 pgvector:给 PostgreSQL 加上向量检索
背景与目标
pgvector(https://github.com/pgvector/pgvector)把向量列做成了普通数据类型:建表加一列 vector(n),存的就是 embedding 的高维数组;再用 <=>(余弦距离)、<->(L2 距离)、<#>(内积)操作符做排序检索。它不需要单独的客户端或服务,PostgreSQL 的生态、权限、备份机制原样复用。
和站里其他中间件不同,pgvector 的"坑"不在部署本身(一条 compose 就起来),而在两个地方:
镜像要选带 vector 扩展的:普通
postgres镜像不带扩展,得用pgvector/pgvector镜像,并显式CREATE EXTENSION vector。连接与超时配置:容器内用它自带的超管用户连,外侧端口与本机已有 PostgreSQL 错开,空闲会话超时按 RAG 场景设合适值。
本篇对齐本机环境:PostgreSQL 15.6(Alpine),镜像钉到 pg15。
步骤
第 0 步:确认 Docker 就绪
docker version
docker compose version第 1 步:准备目录与写 docker-compose.yaml
新建目录并写 docker-compose.yaml,整段复制:
services:
pgvector:
image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/pgvector/pgvector:pg15
restart: always
environment:
PGUSER: postgres
# 默认 postgres 用户的密码(换成你自己的强密码)
POSTGRES_PASSWORD: YourStrong!Passw0rd
# postgres 数据目录
PGDATA: /var/lib/postgresql/data/pgdata
POSTGRES_MAX_CONNECTIONS: 500
# 空闲事务超时(毫秒)
POSTGRES_IDLE_IN_TRANSACTION_SESSION_TIMEOUT: 30000
# 空闲会话超时(毫秒,PostgreSQL 14+)
POSTGRES_IDLE_SESSION_TIMEOUT: 600000
volumes:
- ./volumes/pgvector/data:/var/lib/postgresql/data
ports:
- "5433:5432"
healthcheck:
test: [ "CMD", "pg_isready" ]
interval: 1s
timeout: 3s
retries: 30要点:
镜像:
pgvector/pgvector:pg15,镜像带 vector 扩展,走华为云源。版本 tag 对齐本机 PostgreSQL 15.6。PGUSER: postgres:容器内默认超管用户名。没设POSTGRES_DB时,默认库名也是postgres。PGDATA指向数据目录内层pgdata,配合数据卷./volumes/pgvector/data:/var/lib/postgresql/data落盘。端口
5433:5432:本机已有 PostgreSQL 占用了5432,这里外侧换成5433错开,互不干扰。两个超时:
POSTGRES_IDLE_IN_TRANSACTION_SESSION_TIMEOUT掐掉长时间卡在事务里的连接;POSTGRES_IDLE_SESSION_TIMEOUT(PostgreSQL 14+ 才有)回收单纯空闲的连接。RAG 场景下海量小查询容易堆积空闲连接,设个超时防止连接数被占满。healthcheck:用
pg_isready做就绪探针,等容器真正能接受连接再判断"起来了",而不是只看进程在跑。
第 2 步:启动并确认就绪
docker compose up -d等健康检查通过(restart: always + healthcheck 会在就绪后才标 healthy)。看状态与日志:
docker compose ps
docker compose logs pgvector日志出现 database system is ready to accept connections 即启动完成。
第 3 步:开 vector 扩展并验证
进入容器,用容器内超管连到默认 postgres 库,开扩展:
docker compose exec pgvector psql -U postgres -d postgres -c "CREATE EXTENSION IF NOT EXISTS vector;"验证扩展真的可用——构造一个三维向量并输出它:
docker compose exec pgvector psql -U postgres -d postgres -c "SELECT '[1,2,3]'::vector;"能返回 [1,2,3] 即扩展就绪。再验证一个真实的相似度检索:
-- 在临时表里试向量检索
SELECT '[1,1,1]'::vector <=> '[1,1,2]'::vector AS cosine_dist;cosine_dist 是两点间余弦距离,值越小越相似。
第 4 步:从宿主机连一次(可选,确认发布端口通)
如果宿主机上装有 psql(或用 DBeaver / pgAdmin):
psql -h localhost -p 5433 -U postgres -d postgres走到 postgres=# 提示符即成功。退出用 \q。这一条验证的是"外侧 5433 → 容器 5432"的端口映射是否打通。
踩坑与解决
1. 初始化后改密码不生效,得像 SQL Server/MySQL 那样删卷
问题:容器跑起来后,改
POSTGRES_PASSWORD再docker compose up -d,密码没变。复现:用新密码连,报
password authentication failed。根因:
POSTGRES_*环境变量只在空数据目录首次初始化时生效一次;数据目录一旦生成,改 compose 不会重来。这是 PostgreSQL 官方镜像的通用行为,和站里 MySQL/SQL Server 那几篇同理。解决:要重置,删掉数据卷重建:
docker compose down -v && docker compose up -d(会丢数据,确认可丢再执行)。验证:重建后用新密码能连上。
2. 误用普通 postgres 镜像,没有 vector 扩展
问题:
docker compose exec ... psql -c "CREATE EXTENSION vector;"报extension "vector" is not available。复现:镜像写成了普通
postgres:15,开扩展失败。根因:
vector扩展不在官方postgres镜像里,只有pgvector/pgvector镜像预置。解决:改用
swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/pgvector/pgvector:pg15(或pgvector/pgvector:pg15)。验证:
SELECT '[1,2,3]'::vector;能返回向量。
3. 外侧端口与已有 PostgreSQL 冲突
问题:
docker compose up报端口被占,或连到的是本机另一个 PostgreSQL。复现:外侧端口写成
5432:5432,本机已有 PostgreSQL 占用 5432。根因:本机已装/跑过 PostgreSQL,5432 被占是"通用坑"。
解决:外侧端口换成
5433:5432,连接时用localhost:5433。验证:
psql -h localhost -p 5433 -U postgres能连到的是 pgvector 容器。
通用坑
数据丢了:没挂数据卷,容器销毁即丢。本教程已挂
./volumes/pgvector/data。容器秒退:先看
docker compose logs pgvector,通常是密码/数据目录配置问题。
小结与参考
用 Docker 部署 pgvector:
pgvector/pgvector:pg15镜像 +CREATE EXTENSION vector,一份docker-compose.yaml落地。本篇核心矛盾:pgvector 不是新数据库,而是 PostgreSQL 的扩展——选对带 vector 的镜像、显式开扩展,连接与超时配好即可。
环境变量只在首次初始化生效,改密码要
down -v重建。外侧端口用 5433 与本机已有 PostgreSQL 错开;两个空闲超时防止 RAG 场景的连接堆积。
就绪判断用 healthcheck(
pg_isready),看 healthy 而不是进程。
参考:
pgvector 官方仓库:https://github.com/pgvector/pgvector
pgvector 文档:https://github.com/pgvector/pgvector#readme
PostgreSQL 官方文档:https://www.postgresql.org/docs/
镜像:
swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/pgvector/pgvector:pg15

