首页
/ Immich 自托管照片与视频管理:功能矩阵全景解析与源码实现验证

Immich 自托管照片与视频管理:功能矩阵全景解析与源码实现验证

2026-09-06 11:50:22作者:俞予舒Fleming

本文以 Immich 项目 README 的阿拉伯语本地化版本(README_ar_JO.md)为主体,完整继承其中的项目定位、备份安全提示、演示环境访问方式与「移动端 / Web 端」功能矩阵,并结合仓库中的服务端源码逐项验证这些特性的真实实现位置,同时给出基于 Docker Compose 的部署关键配置,帮助读者在评估与落地一套自托管照片视频管理方案时做到「功能可核对、实现可溯源、部署可复制」。

Immich Web 界面主截图

项目定位与核心主张

README(含 阿拉伯语版本)对项目的一句话定义是:「高性能的自托管照片与视频管理解决方案」(High performance self-hosted photo and video management solution)。这一定位包含三个关键词:

  • 自托管(self-hosted):整套系统由用户在自己的服务器或家用设备上运行,数据完全掌握在自己手中,而非上传到云端厂商;
  • 高性能:从服务端实现看,搜索、缩略图、转码等重任务通过任务队列与机器学习容器解耦(见后文部署章节),而非阻塞在 API 请求中;
  • 照片与视频统一:同一套资产(asset)模型同时管理图片与视频,支持 RAW 格式、LivePhoto/MotionPhoto 等格式。

项目采用 AGPLv3 许可证(README 顶部徽章即标明),这一点对评估二次开发与商业化集成至关重要。

备份安全提示(原文档的重要警示)

原 README 以醒目的 WARNING 区块强调:

对于你珍贵的照片和视频,务必始终遵循 3-2-1 备份策略(3 份副本、2 种介质、1 份异地)。

这是自托管方案的通用红线:Immich 管理的是「唯一原始」,一旦本地存储损坏且无副本,数据不可恢复。仓库文档中还提供了服务器端备份恢复的专门指南,参见 备份与恢复文档,其中涵盖了 PostgreSQL 数据库与媒体库目录的备份脚本模板(见 备份脚本模板)。

文档体系与仓库导航

原 README 的「Links」章节将读者导向外部文档站;在本仓库内,这些文档同样以源码形式存在,可按需直接阅读:

主题 仓库内路径
Docker Compose 安装指南 docs/docs/install/docker-compose.mdx
环境变量全集 docs/docs/install/environment-variables.md
生产 Compose 文件 docker/docker-compose.prod.yml
机器学习硬件加速 docs/docs/features/ml-hardware-acceleration.md
系统设置(管理端) docs/docs/administration/system-settings.md
架构说明 docs/docs/developer/architecture.mdx
一键安装脚本 install.sh

演示环境(Demo)

原 README 提供了一套官方演示环境供读者零成本体验:Web 端直接访问演示站点,移动端则将「服务器端点 URL」指向同一演示地址。演示登录凭据如下:

email: demo@immich.app
password: demo

这套演示凭据的意义在于:移动端备份、智能搜索、人脸识别等能力都依赖后端服务(含机器学习容器),本地快速验证不如直接使用演示环境观察效果,再决定是否自托管。

功能矩阵:逐项继承并源码溯源

原 README 的核心内容是「Features」矩阵,按 移动端(Mobile)/ Web 端 两个维度标注每项特性的支持情况。下表完整继承主 README(README.md)的最新矩阵(阿拉伯语版本的矩阵与之一致,仅个别行为随版本更新略有滞后),并在每行补充服务端源码依据:

特性 移动端 Web 服务端实现依据
上传与查看视频、照片 Yes Yes asset-media.service.ts
打开 App 时自动备份 Yes N/A 移动端 backup-provider
防止资产重复 Yes Yes duplicate.service.ts
选择性相册备份 Yes N/A 同上(备份策略在移动端执行)
下载照片视频到本地 Yes Yes download.service.ts
多用户支持 Yes Yes user-admin.service.ts
相册与共享相册 Yes Yes album.service.ts
可拖动滚动条 Yes Yes 前端能力(Web 端 Svelte 实现)
RAW 格式支持 Yes Yes media.service.ts
元数据查看(EXIF、地图) Yes Yes metadata.service.ts
元数据/物体/人脸/CLIP 搜索 Yes Yes search.service.ts
管理功能(用户管理) No Yes user-admin.service.ts
后台备份 Yes N/A 移动端系统级同步任务
虚拟滚动 Yes Yes 前端能力(两端列表渲染)
OAuth 支持 Yes Yes auth.service.ts
API 密钥 N/A Yes api-key.service.ts
LivePhoto/MotionPhoto 备份与回放 Yes Yes asset-file.service.ts
360 度全景图显示 No Yes Web 端渲染能力
用户自定义存储结构 Yes Yes storage-template.service.ts
公开分享 Yes Yes shared-link.service.ts
归档与收藏 Yes Yes asset.service.ts
全球地图 Yes Yes map.service.ts
合作伙伴共享 Yes Yes partner.service.ts
人脸识别与聚类 Yes Yes person.service.ts
回忆(x 年前的今天) Yes Yes memory.service.ts
离线支持 Yes No 移动端本地数据库(drift)
只读图库 Yes Yes 用户权限体系
堆叠照片(Stacked Photos) Yes Yes stack.service.ts
标签(Tags) No Yes tag.service.ts
文件夹视图(Folder View) Yes Yes 资产元数据中的文件夹字段

下面对矩阵中最具技术含量的几项能力做源码级解读。

智能搜索:元数据、地理、人脸与 CLIP 四类检索的统一入口

SearchService 是搜索能力的统一入口,暴露了多组搜索方法:

  • searchMetadata:按 EXIF 元数据(相机、镜头、时间范围等)与校验和检索,内部将 checksum 按长度判定为 base64 或 hex 解码后交给仓库层查询(search.service.ts);
  • searchSmart:即「CLIP 语义搜索」。从源码结构看,其核心是 resolveEmbedding 将查询文本/图像转换为向量 embedding,再通过 PostgreSQL 的向量检索能力匹配资产——这就是「搜索 日落 照片」这类自然语言检索的底层机制(search.service.ts);值得注意的是 searchSmart 会先检查机器学习服务配置,未启用时直接抛出 Smart search is not enabled,说明智能搜索强依赖独立的机器学习容器
  • searchPlaces / getExploreData:基于 EXIF 城市字段的地理检索与探索页(按城市分组、按时间倒序);
  • 所有搜索路径都统一执行 visibility(可见性策略)与 userIds(多用户/合作伙伴范围)过滤,即「合作伙伴共享」能力直接内嵌在搜索的数据可见性里。

人脸识别与聚类:PersonService 与 ANN 向量索引

人脸识别由 PersonService 管理。从源码结构看:

  • 人物(person)以 personGroupId 跨用户归属标识,getAll 支持「以某张人脸为起点」的最近邻分页(closestFaceAssetId / closestPersonId 参数),这正是人物聚类浏览中「从一张脸滑到相似的脸」的支撑逻辑(person.service.ts);
  • reassignFaces 实现了手动合并人脸:将误分组的脸重新指派到目标人物,并在人物缺省封面时自动更新特征照片。

人脸向量索引并非放在主库内,而是由独立的 Python ANN 服务承载:machine-learning/ann 提供了 C++ 实现的近似最近邻索引,ML 侧会话封装见 machine-learning/immich_ml/sessions/ann。这与 compose 文件中独立的 immich-machine-learning 容器一一对应。

Memories:后台任务驱动的「多年前的今天」

「回忆(x years ago)」在 Web 与移动端均支持,其服务端实现是典型的后台 Job 模式MemoryService 通过 @OnJob({ name: JobName.MemoryGenerate, queue: QueueName.BackgroundTask }) 装饰器挂到后台任务队列,由 job.service.ts 统一调度。生成逻辑为:以当天为锚点向前回看 3 天(常量 DAYS = 3,容忍任务延迟),在数据库锁 DatabaseLock.MemoryCreation 保护下遍历所有用户,按「同一天(month-day)」聚合历年资产生成 OnThisDay 类型记忆,并通过 SystemMetadataKey.MemoriesState 记录进度避免重复生成。

这套「Job 装饰器 + 队列 + 系统元数据游标」的机制是 Immich 服务端批量任务(缩略图、转码、OCR、人脸检测等)的通用范式,参见 任务与工作器文档

重复资产检测:基于校验和的分组与合并

「防止资产重复」由 DuplicateService 实现:

  • 检测由后台 Job 触发(OnJob 装饰器),从源码结构看按 checksum 分组识别重复项,并可通过 suggestDuplicateKeepAssetIds 给出「保留哪一张」的建议;
  • 解决(resolve)阶段会合并相册(mergedAlbumIds)、合并标签(mergedTagIds / mergedTagValues),并对坐标等 EXIF 字段做去空合并(duplicate.service.ts)——即删除重复资产前先把其从属关系完整转移到保留资产上。

公开分享与合作伙伴共享

两个共享特性在架构上泾渭分明:

  • 公开分享:由 shared-link.service.ts 生成独立链接,无需登录即可访问指定相册。从 SearchService 的可见性逻辑可以印证:持有 sharedLink 凭据的会话只能配合 albumIds 过滤使用,否则直接抛错,说明分享链接的作用域被严格限定在单个相册边界内;
  • 合作伙伴共享(Partner Sharing):由 partner.service.ts 管理,是「双向只读」的用户间资产共享——双方可互相查看对方的时间线资产,但不可编辑。搜索路径中的 getMyPartnerIds(见 search.service.ts 顶部导入)证实合作伙伴范围被织入了所有资产检索。

API 密钥:面向脚本与第三方集成的鉴权方式

矩阵中「API Keys」仅 Web 端支持(移动端不使用)。服务端由 api-key.service.ts 提供创建与管理;Web 端在用户设置中生成密钥后,可将其用于 OpenAPI 客户端。完整的接口契约以 OpenAPI 规范形式维护在 open-api/immich-openapi-specs.json,官方 SDK 见 packages/sdk 与命令行工具 packages/cli,社区指南 Python 文件上传示例 展示了密钥的实际用法。

部署视角:功能矩阵背后的四个容器

README 的功能之所以能成立,依赖 docker/docker-compose.yml 定义的四容器拓扑,这也是理解「Web 端能做什么、移动端能做什么」的前提:

容器 镜像 职责
immich_server ghcr.io/immich-app/immich-server:${IMMICH_VERSION:-release} API 与 Web 前端,端口 2283,媒体目录挂载 ${UPLOAD_LOCATION}:/data
immich_machine_learning ghcr.io/immich-app/immich-machine-learning:${IMMICH_VERSION:-release} 人脸识别、CLIP 向量、OCR;可加 -cuda/-rocm/-openvino/-armnn/-rknn 后缀启用硬件加速
immich_redis valkey/valkey:9(固定摘要) 任务队列与缓存(服务端 depends_on 其就绪)
immich_postgres vectorchord + pgvectors 扩展的定制 postgres 14 镜像 主数据库,同时承载 CLIP/人脸向量检索

关键环境变量定义在 docker/example.env

  • UPLOAD_LOCATION=./library:上传文件存储位置(compose 中挂载为 /data);
  • DB_DATA_LOCATION=./postgres:PostgreSQL 数据目录,文档明确不支持网络共享存储
  • DB_PASSWORD:官方示例默认为 postgres,必须改为仅含 A-Za-z0-9 的随机口令;
  • IMMICH_VERSION:当前示例固定为 v3,可进一步钉到具体小版本如 v2.1.0

仓库根目录还提供了一键安装脚本 install.sh,其流程为:创建 ./immich-app 目录 → 下载当前发布的 docker-compose.ymlexample.env → 用 sha256sum 派生随机数据库密码替换默认值 → 执行 docker compose up --remove-orphans -d 启动。compose 文件头部注释特别提示:请以当前 release 发布的 compose 文件为准,main 分支版本可能与最新发布不兼容。

小结

Immich 的 README 功能矩阵并非营销清单:智能搜索对应 SearchService 的 embedding 检索与 ML 容器联动,人脸识别对应 PersonService + 独立 ANN 索引服务,回忆功能对应带数据库锁与进度游标的后台 Job,重复检测对应基于 checksum 的分组合并,分享则分为 shared-link(外链)与 partner(双向只读)两条正交路径。配合四容器 Compose 拓扑与 .env 的少量关键配置,读者既能按矩阵评估功能边界,也能沿文内给出的源码路径逐条验证实现。

登录后查看全文
热门项目推荐
相关项目推荐