0
0
0

Docker 部署 pgvector:给 PostgreSQL 加上向量检索

2026-11-04
文章摘要
|

背景与目标

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 而不是进程。

参考:

支持与分享

如果这篇文章对你有帮助,欢迎分享给更多人或者给予支持!

Docker 部署 pgvector:给 PostgreSQL 加上向量检索
/archives/01a1a59d-f289-733e-bfcc-0e5e1d489712
作者
隔壁老陈
发布于
2026-11-04
许可协议
CC BY-NC-SA 4.0

评论