首页
/ Immich 升级指南:Docker Compose 版本升级、语义化版本策略与迁移到 VectorChord 向量扩展

Immich 升级指南:Docker Compose 版本升级、语义化版本策略与迁移到 VectorChord 向量扩展

2026-09-04 20:37:45作者:霍妲思

本文基于 Immich 官方文档 升级指南 整理并扩充,面向自托管的 Immich 运维者:你将学会如何安全地完成版本升级与重启、理解 Immich 的语义化版本策略(含移动客户端与服务端的兼容性规则),以及最关键的——如何把旧的 pgvecto.rs 向量数据库扩展迁移到其继任者 VectorChord,包括完整的 docker-compose.yml 修改对照与源码层面的迁移验证机制。

升级前的准备:关注破坏性变更

当 Immich 发布新版本时,官方建议先阅读 release notes,重点核对其中标注的破坏性变更(breaking changes),再决定何时升级。如果你没有阅读过变更记录,至少要知道两件事:

  • 破坏性变更(包括 API 与部署方式的变更)原则上只出现在 major 版本中;
  • 切换向量扩展(pgvecto.rs → VectorChord)这一类变更一旦完成,数据库方向不可逆(后文会详述降级限制)。

如果你的 .env 文件中显式设置了 IMMICH_VERSION 变量,升级前需要把它改成最新或期望的版本号。从仓库内的 compose 文件可以看到,各服务镜像的 tag 都来自这个变量(默认为 release),例如 docker/docker-compose.yml 中的 image: ghcr.io/immich-app/immich-server:${IMMICH_VERSION:-release},因此只改 .env 而不 pull 新镜像是不会生效的。

使用 Docker Compose 升级并重启

在包含 docker-compose.yml 的目录下执行:

docker compose pull && docker compose up -d

这条命令先拉取按 IMMICH_VERSION 指定的新镜像,再重建有变更的容器。升级完成后,旧版本的容器镜像已无用武之地,可以用以下命令清理磁盘空间:

docker image prune

需要提醒的是:Immich 官方要求使用当前 release 版本附带的 docker-compose.yml(仓库根目录的 docker/docker-compose.yml 文件头部注释也明确写了"compose 文件以当前 release 提供的为准,main 分支上的文件可能与最新 release 不兼容"),因此每次升级时建议同步更新 compose 文件本身,而不仅仅是镜像 tag——因为新版本的 compose 可能调整了服务定义(例如数据库服务的 healthcheck 与启动参数)。

版本策略(Versioning Policy)

Immich 遵循语义化版本(semantic versioning),版本号格式为 <major>.<minor>.<patch>。官方计划将破坏性变更(含 API 与部署方式)限制在 major 版本内。

使用 metatag 锁定主版本

你可以把 Docker 镜像指向当前主版本的元标签(metatag),例如 :v3,这样每次 pull 都会自动获取该主系列下的最新版本。需要注意的是:metatag 不跟随 release candidates(RC),如果你依赖 RC 版本应显式指定完整版本号。

移动端与服务端的兼容性规则

这是升级顺序中最容易踩坑的一条规则:

  • 移动端 App:通常兼容当前主版本及上一个主版本的服务端;
  • 服务端:只与相同主版本的移动端兼容。

因此官方推荐先升级所有移动客户端,再升级服务端,以确保兼容性。如果你的手机端 App 还停留在旧主版本,先升级服务端可能导致移动端功能不可用。

补丁回移与降级限制

  • 官方不会把补丁回移(backport)到更早的版本,建议所有用户保持最新稳定版;
  • 降级不被支持,即使在同一个小版本内降级也不行。

迁移到 VectorChord

Immich 已把向量索引从已废弃的 pgvecto.rs 数据库扩展迁移到其继任者 VectorChord,后者在各方面都带来了性能改进(更高的检索性能、更低的内存占用,见 standalone PostgreSQL 文档中的说明)。本节指导你在 Docker Compose 部署下完成这次切换。

先判断自己是否已经在使用 VectorChord

如果你使用 Docker Compose 部署 Immich,docker-compose.yml 中数据库服务使用的是 ghcr.io/immich-app/postgres 镜像,并且没有显式设置 DB_VECTOR_EXTENSION 环境变量,那么你的数据库已经在用 VectorChord,本节不适用

仓库当前的 docker/docker-compose.yml 中数据库镜像正是 ghcr.io/immich-app/postgres:14-vectorchord0.4.3-pgvectors0.2.0@sha256:...,且没有 DB_VECTOR_EXTENSION 配置,印证了这一点。DB_VECTOR_EXTENSION 是服务端环境变量中显式指定向量扩展的开关,源码中 server/src/dtos/env.dto.ts 定义为 z.enum(['pgvector', 'vectorchord']).optional(),并在 server/src/repositories/config.repository.ts 中映射为对应的扩展类型——不设置时,由镜像内置扩展决定实际行为。

反过来,如果你不是通过 Docker Compose 部署(例如使用了第三方发行版),且在服务端启动日志中看到 pgvecto.rs 的弃用警告,应当参考你所用 Immich 发行版维护方的指南,或按你的具体环境适配以下步骤。

第 1 步:备份数据库

在做任何改动之前,请先备份数据库。尽管官方尽可能让这次迁移平滑,但任何数据库级变更都存在出错可能,备份是唯一的安全网。

第 2 步:修改 docker-compose.yml

按以下 diff 修改你的 docker-compose.ymldatabase 服务:

  [...]

  database:
    container_name: immich_postgres
-   image: docker.io/tensorchord/pgvecto-rs:pg14-v0.2.0@sha256:739cdd626151ff1f796dc95a6591b55a714f341c737e27f045019ceabf8e8c52
+   image: ghcr.io/immich-app/postgres:14-vectorchord0.4.3-pgvectors0.2.0
    environment:
      POSTGRES_PASSWORD: ${DB_PASSWORD}
      POSTGRES_USER: ${DB_USERNAME}
      POSTGRES_DB: ${DB_DATABASE_NAME}
      POSTGRES_INITDB_ARGS: '--data-checksums'
+     # Uncomment the DB_STORAGE_TYPE: 'HDD' var if your database isn't stored on SSDs
+     # DB_STORAGE_TYPE: 'HDD'
    volumes:
      # Do not edit the next line. If you want to change the database storage location on your system, edit the value of DB_DATA_LOCATION in the .env file
      - ${DB_DATA_LOCATION}:/var/lib/postgresql/data
-   healthcheck:
-     test: >-
-       pg_isready --dbname="$${POSTGRES_DB}" --username="$${POSTGRES_USER}" || exit 1;
-       Chksum="$$(psql --dbname="$${POSTGRES_DB}" --username="$${POSTGRES_USER}" --tuples-only --no-align
-       --command='SELECT COALESCE(SUM(checksum_failures), 0) FROM pg_stat_database')";
-       echo "checksum failure count is $$Chksum";
-       [ "$$Chksum" = '0' ] || exit 1
-     interval: 5m
-     start_interval: 30s
-     start_period: 5m
-   command: >-
-     postgres
-     -c shared_preload_libraries=vectors.so
-     -c 'search_path="$$user", public, vectors'
-     -c logging_collector=on
-     -c max_wal_size=2GB
-     -c shared_buffers=512MB
-     -c wal_compression=on
+   shm_size: 128mb
    restart: always

    [...]

要点说明:

  • 镜像替换:从 docker.io/tensorchord/pgvecto-rs:pg14-v0.2.0 换成 ghcr.io/immich-app/postgres:14-vectorchord0.4.3-pgvectors0.2.0。新镜像在 PostgreSQL 中同时内置 VectorChord、pgvector 和 pgvecto.rs 三种扩展(保留后两者是为了兼容旧备份的恢复);
  • 被删掉的 healthcheck 与 command:这些配置(含数据校验和检查、shared_preload_libraries 调优、shared_buffers=512MBwal_compression 等)已经被整合进镜像内部,并附带了额外调优,所以 compose 文件里可以整段删除,健康检查本身并没有被移除;
  • 新增 shm_size: 128mb:为新镜像下的 PostgreSQL 共享内存配置;
  • DB_STORAGE_TYPE: 'HDD'(默认注释掉):SSD 与 HDD 性能特征不同,最优配置也不同——两套配置在两种介质上都能跑,但配对了介质才会更快。默认按 SSD 调优,如果你的数据库不在 SSD 上,把这一行取消注释。通用建议:尽可能把数据库放在 SSD 上。

第 3 步:非默认镜像的 tag 对照

上面的 diff 以默认镜像 pg14-v0.2.0 为基准。如果你偏离过默认的 pg 主版本或 pgvecto.rs 版本,必须相应调整新镜像 tag 中的两个版本号:PostgreSQL 主版本pgvecto.rs 版本。例如,如果之前的镜像是 docker.io/tensorchord/pgvecto-rs:pg16-v0.3.0,那么新镜像应为 ghcr.io/immich-app/postgres:16-vectorchord0.3.0-pgvectors0.3.0,而不是照抄 diff 中指定的 tag。

第 4 步:正常启动,等待自动重建

改完后像平常一样启动 Immich 即可。Immich 会在启动时自动完成数据库层面的变更,耗时从几秒到几分钟不等,取决于硬件与图库规模。

特别要注意:如果 Immich 中资产超过 10 万张,或服务器配置较弱,服务端日志会看似卡住Reindexing clip_indexReindexing face_index 一段时间,这是正常现象——只要没有报错,耐心等待即可。从源码看,这一步对应 server/src/services/database.service.ts 在启动时调用 reindexVectorsIfNeeded([VectorIndex.Clip, VectorIndex.Face])server/src/repositories/database.repository.ts 中的实现会检查现有索引定义:对 VectorChord 索引,它核对索引是否为 using vchordrq、并依据表行数计算目标 lists 数量(带一个 slack 因子避免行数在临界值附近时反复重建),不匹配则触发重建——所以"重建向量索引"正是迁移期间日志的主要活动。同一个启动流程还提示:如果直接来自 1.107.2 之前的老版本升级,应先升到 1.107.2 再走当前升级。

降级限制(重要)

切换到 VectorChord 之后,不应再把 Immich 降级到 1.133.0 以下。这叠加了前文"降级本身即不受支持"的规则,意味着 VectorChord 迁移实际上是一条单向路径,请在执行前确认当前版本稳定。

VectorChord 常见问题(FAQ)

Q:我有多服务共享的独立 PostgreSQL 实例,怎么切换到 VectorChord? 参见standalone PostgreSQL 文档中的迁移说明。迁移路径取决于你当前用的是 pgvecto.rs 还是 pgvector,以及 Immich 是否拥有 superuser 数据库权限。该文档同时给出了兼容约束:pgvector 需为 >= 0.7, < 0.9,VectorChord 接受范围为 >= 0.3, < 2.0,Immich 服务端会在启动时校验 VectorChord 版本,不满足则拒绝启动。

Q:为什么 diff 删掉了这么多行?健康检查被移除了吗? 没有。这些行连同额外调优一起被整合进了镜像本身。

Q:这次变更对现有数据库备份意味着什么? 新数据库镜像在 VectorChord 之外还包含 pgvector 和 pgvecto.rs,因此可以用它恢复使用过这三种扩展中任意一种的旧备份。但注意反向约束:切换到 VectorChord 之后新做的备份,恢复时必须使用包含 VectorChord 的镜像。

Q:迁移完成后还需要保留 pgvecto.rs 吗? pgvecto.rs 只在迁移期间(或需要恢复含 pgvecto.rs 的旧备份时)才有必要。为了更精简的数据库与更小的镜像,迁移完成并确认 Immich 正常启动后,可以可选地换用不含 pgvecto.rs 的镜像变体:ghcr.io/immich-app/postgres:14-vectorchord0.4.3(PostgreSQL 版本号按你的实际情况替换)。

Q:数据库在 SSD 还是 HDD 上为什么重要? 见上文 DB_STORAGE_TYPE 说明:两种介质性能特征不同,SSD 的最优配置与 HDD 不同,正确配置能让 Immich 响应更快。

Q:这个新数据库镜像可以脱离 Immich 当通用 PostgreSQL 镜像用吗? 可以。它是一个标准 PostgreSQL 容器镜像,额外附带 VectorChord、pgvector 以及(可选的)pgvecto.rs 扩展。如果你之前把旧 pgvecto.rs 镜像用于其他用途,可以同样改用这个镜像。

小结

  • 常规升级:更新 .env 中的 IMMICH_VERSIONdocker compose pull && docker compose up -ddocker image prune 清理旧镜像;
  • 升级顺序:先移动端、后服务端(服务端只兼容相同主版本的客户端);
  • VectorChord 迁移:备份 → 按 diff 改 compose(换镜像、删旧 healthcheck/command、加 shm_size、按需开 HDD 配置)→ 正常启动等待 Reindexing clip_index / Reindexing face_index 完成 → 之后不可降级到 1.133.0 以下;
  • 遇到迁移问题,可参考 standalone PostgreSQL 迁移章节 与仓库服务端源码 server/src/services/database.service.tsserver/src/repositories/database.repository.ts 中向量索引的校验与重建逻辑进一步定位。
登录后查看全文
热门项目推荐
相关项目推荐