logo
0
0
WeChat Login

Ubuntu 24.04 + PostgreSQL 17 Docker 部署

PostgreSQL 17 + pgvector + pg_jieba + pg_textsearch,多阶段构建,面向所有 CPU 通用不依赖任何外部数据

设计契约(修改前请阅读)

镜像构建 + 启动严格遵守以下三条:

  1. CPU 适配可选开关:默认直接复用 base image 自带的科学计算扩展二进制(构建快、依赖少)。如果目标机 CPU 比 base image 构建机更老或缺少同等 SIMD 扩展,传 CPU_PORTABLE_BUILD=true 触发镜像内 portable rebuild:使用通用 CFLAGS(-march=x86-64/-march=armv8-a + -mtune=generic + -fno-tree-vectorize/-fno-tree-loop-vectorize/-fno-tree-slp-vectorize),避免 Illegal instruction该 ARG 只控制 CPU 适配,不影响扩展是否安装/启用。
  2. 扩展默认安装并启用pgvector / pg_textsearch / pg_jieba / pg_trgm / unaccent / ltree / hstore / pg_stat_statements 全部默认安装并在 template1CREATE EXTENSION,业务库(含未来 CREATE DATABASE 创建的新库)自动继承。
  3. 不依赖外部数据 / initdb 不写业务数据:镜像构建过程不拉取任何业务数据(CPU_PORTABLE_BUILD=true 时只 git clone pgvector 源码)。运行期不再 bind-mount 任何 host 路径用于初始化(jieba 词典、init SQL、entrypoint 全部内置进镜像)。首启只做 initdb + 在 template1 创建扩展 + 创建 POSTGRES_DBTEMPLATE template1)。没有 schema 自动导入,没有 bundle 自动导入。

如需把外部 dump 导进数据库,使用 /usr/local/bin/import-migrate.sh显式触发

文件清单

文件作用
Dockerfile多阶段:vector-builder 重编 pgvector → 运行镜像复制内置资产
docker-compose.yml主部署文件,已挂载 /tmp/migrate -> /migrate:ro
docker-compose.jieba-test.yml第二实例,端口 55432,独立 data 目录
scripts/entrypoint.sh启动脚本(initdb + 扩展,无业务数据
scripts/process-init-files.sh/docker-entrypoint-initdb.d/ 调度
scripts/import-migrate.sh显式导入 /migrate/*.{dump,sql,sql.gz,sql.xz}
init/001_extensions.sqlCREATE EXTENSION
conf/postgresql.conf启动配置模板
jieba/dicts/novel_analyzer.dict唯一保留的用户词典
build_pgsql.sh裸机/VM 全量编译脚本(与 Dockerfile 同样的 portable CFLAGS)
verify-running.sh / check-pg-capabilities.sh健康自检

默认凭据

POSTGRES_USER     d2
POSTGRES_PASSWORD d2pass
POSTGRES_DB       d2
PGPORT            5432

可通过 compose environment:.env 覆盖。

启动

cd /home/user/pgsql17-ubuntu24
bash build-and-up.sh

仅查看计划:

DRY_RUN=true bash build-and-up.sh

连接

docker exec -it d2-pg17 /opt/postgresql/bin/psql -U d2 -d d2

检查扩展

SELECT extname FROM pg_extension ORDER BY extname;

预期至少包含:pg_textsearchpg_jiebavectorpg_trgmunaccentltreehstorepg_stat_statements

/tmp/migrate 导入数据库(按需)

docker-compose.yml 已默认挂载:

volumes:
  - /tmp/migrate:/migrate:ro

容器启动不会自动导入,需要显式执行:

# 导入全部支持的文件(按 *.sql -> *.sql.gz -> *.sql.xz -> *.dump 顺序)
docker exec -it d2-pg17 import-migrate.sh

# 只导一个文件(相对 /migrate 或绝对路径都行)
docker exec -it d2-pg17 import-migrate.sh novel_analyzer.dump

# 指定目标库
docker exec -it d2-pg17 import-migrate.sh -d d2 novel_analyzer.sql.gz

支持格式:

格式处理方式
*.dumppg_restore --no-owner --no-privileges --exit-on-error
*.sqlpsql -f
*.sql.gz / *.sql.xz解压后管道喂给 psql
*.tar.gz / *.tar忽略(视为数据集而非 DB dump)

提示:/tmp/migrate/novel_analyzer.dump 是 PostgreSQL 17.5 自定义格式 dump,已用 pg_jieba/pg_textsearch/vector 扩展,导入前确保扩展已创建。

jieba 词典

镜像只保留 novel_analyzer.dict(构建期复制到 /opt/pg_jieba/dicts/,启动时同步到 /opt/postgresql/share/tsearch_data/)。

如需新增用户词典:

  1. *.dict 放进 jieba/dicts/
  2. 在 compose PG_JIEBA_USER_DICT 中加入文件名(去掉 .dict
  3. 重新 build

CPU 兼容性说明 / 是否要开启 portable build

之前现象:

server process was terminated by signal 4: Illegal instruction

根因:上游预编译的 vector.so 带宿主机指令集优化(AVX2 / AVX-512),跑在不支持的 CPU 上就会 SIGILL。

CPU_PORTABLE_BUILD 这个 ARG 控制的是是否在镜像里以 portable CFLAGS 重新编译科学计算扩展(当前是 pgvector;未来若新增其它带 SIMD 的扩展会一并走这个分支)。它只关 CPU 适配,扩展始终默认安装并启用。

默认行为(CPU_PORTABLE_BUILD=false

直接复用 base image 自带的二进制:

  • 构建最快(仅一次 COPY
  • 完全不依赖外网
  • 风险:如果你的 CPU 比 base image 构建机老 / 不支持同等 SIMD,会 SIGILL

开启 portable build(CPU_PORTABLE_BUILD=true

docker-compose build --build-arg CPU_PORTABLE_BUILD=true
# 或一次性环境变量
CPU_PORTABLE_BUILD=true bash build-and-up.sh

构建期 git clone pgvector ${PGVECTOR_VERSION},使用通用 CFLAGS:

make PG_CONFIG=/opt/postgresql/bin/pg_config OPTFLAGS="" \
     PG_CFLAGS="-march=x86-64 -mtune=generic -O2 \
                -fno-tree-vectorize -fno-tree-loop-vectorize -fno-tree-slp-vectorize"

aarch64 自动切 -march=armv8-a

portable 与 native 性能差距(评估开 native 的收益)

场景主要瓶颈native 相比 portable备注
高维稠密向量距离(dim ≥ 768,BGE-M3=1024,OpenAI=1536)SIMD 累加(dot / sqdiff)2.0-4.0x(AVX-512 上限更高)pgvector 最热的内循环
HNSW 批量建索引反复距离计算1.5-3.0x大批量入库时受益最明显
HNSW / IVFFlat 在线 ANN 查询距离 + 索引遍历1.2-2.0x 端到端索引开销稀释了 SIMD 收益
低维(dim ≤ 128)或低 QPSI/O / 元组扫描< 1.1x(基本无差)SIMD 不是瓶颈

何时考虑放开 native(额外加 -march=native,目前未实现,按需扩展):

  1. 嵌入向量维度高,ANN 检索是关键路径
  2. 大批量 HNSW 建索引
  3. 部署机和构建机 CPU 一致或更新(不会跨机分发)

保持 portable 的原因

  • 镜像跨多种 CPU 分发
  • 向量检索不是热路径
  • 即使开 CPU_PORTABLE_BUILD=true,编出的 vector.so 也是 portable 的,性能与 base image 内置版本几乎一致——它解决的是「能跑」而非「跑得快」

build_pgsql.sh 走完全相同的 portable CFLAGS 路径。

停止

docker-compose down

已发布镜像

TagBuild 模式适用机器
registry.cn-chengdu.aliyuncs.com/rapid7/pgsql17-ubuntu24-pg17:v2CPU_PORTABLE_BUILD=false(默认 base)与 base image 构建机指令集兼容(含 AVX2/AVX-512 等)的现代 x86_64
registry.cn-chengdu.aliyuncs.com/rapid7/pgsql17-ubuntu24-pg17:v2-i7-8865uCPU_PORTABLE_BUILD=true(portable rebuild)老 CPU / 缺 SIMD(如 i7-8865U / Whiskey Lake、轻量虚机、ARM 机器)—— 跑默认 v2 出现 Illegal instruction 时换这个

拉镜像(无脑选):先试 :v2,启动后 CREATE EXTENSION vectorIllegal instruction 就改用 :v2-i7-8865u

或者先用 verify-image.sh 验过:

sudo docker pull registry.cn-chengdu.aliyuncs.com/rapid7/pgsql17-ubuntu24-pg17:v2
bash scripts/verify-image.sh registry.cn-chengdu.aliyuncs.com/rapid7/pgsql17-ubuntu24-pg17:v2

启动后校验

bash verify-running.sh
bash check-pg-capabilities.sh

一键全量校验(推荐)

scripts/verify-image.sh 会拉起一个临时容器对指定镜像跑 25 项端到端检查(扩展存在性 + 行为 + template1 继承 + 镜像内置资产 + import 工具),自动清理。

# 默认校验本地构建镜像
bash scripts/verify-image.sh

# 校验远端镜像(先 pull)
sudo docker pull registry.cn-chengdu.aliyuncs.com/rapid7/pgsql17-ubuntu24-pg17:v2
bash scripts/verify-image.sh registry.cn-chengdu.aliyuncs.com/rapid7/pgsql17-ubuntu24-pg17:v2

# 自定义端口(避开 5432 占用)
HOST_PORT=15433 bash scripts/verify-image.sh

预期输出末尾:

PASS=25  FAIL=0
all checks passed

校验项覆盖:

  • vector / pg_textsearch / pg_jieba / pg_trgm / unaccent / ltree / hstore / pg_stat_statements 全部 pg_extension 中可见
  • pgvector 距离运算 + HNSW 索引创建 + ANN top-1 查询
  • pg_jieba 分词 + pg_jieba.user_dict=novel_analyzer 装载
  • template1 已开启扩展,新建 DB 自动继承
  • /opt/pg_jieba/dicts/ 镜像内只剩 novel_analyzer.dict
  • /usr/local/bin/import-migrate.sh 存在且 --help 正常
  • shared_preload_librariespg_jieba

About

pgsql17-ubuntu24

Language
Shell90.1%
Dockerfile9.9%