Immich 自托管照片与视频管理方案:功能矩阵、部署配置与源码实现详解
本文基于 Immich 仓库的巴西葡萄牙语官方 README(README_pt_BR.md)展开,完整解读该自托管照片/视频管理系统的功能矩阵(移动端 vs Web 端能力对照)、部署架构与环境变量配置,并结合服务端、Web 端与移动端的实际源码逐项印证各项特性的底层实现,帮助你在部署前建立对 Immich 能力边界与落地方式的完整认知。
一、项目定位与核心主张
Immich 的官方定位是一句简洁的描述:“Solução self-hosted de alta performance para backup de fotos e vídeos”(高性能的自托管照片与视频备份方案)。项目采用 AGPL v3 开源许可证发布,这是一个需要在使用前明确知晓的合规前提——其分发与修改受 AGPLv3 条款约束。
文档开头附带两条重要提示,值得自托管用户重视:
- 备份策略警告:官方明确要求对珍贵媒体遵循 3-2-1 备份原则 的完整理念(3 份副本、2 种介质、1 份异地)。换言之,Immich 是照片视频的集中管理与增量备份层,而不是唯一的备份保障,生产使用应配合外部备份策略;
- 文档指引:主文档(含完整安装指南)位于官方站点,本仓库内的
docs/目录即其源码,可直接查阅各主题的安装与环境变量说明。
二、在线演示与体验入口
README 中提供了官方演示环境的完整说明:
- 演示站入口为
demo.immich.app(详见官方文档与仓库 README 原文); - 在移动端 App 中,将
Server Endpoint URL字段填入https://demo.immich.app即可登录体验; - 演示登录凭据:
| 邮箱(Email) | 密码(Senha) |
|---|---|
| demo@immich.app | demo |
演示环境覆盖的功能与功能矩阵一致,适合在本地部署前先验证交互流程(时间线浏览、相册、人脸分组、搜索等)。
三、功能矩阵逐项解读(移动端 × Web 端)
README 的核心骨架是下面这张特性对照表。它按“功能 / 移动 App / Web”三列组织,如实标注了每个能力在两端的可用情况(Sim = 支持,N/A = 不适用,Não = 不支持)。下表完整保留原文档的全部条目,并补充了分组说明:
| 功能特性 | 移动 App | Web 端 |
|---|---|---|
| 上传与浏览照片和视频 | ✓ | ✓ |
| 打开 App 时自动备份 | ✓ | N/A |
| 防止文件重复 | ✓ | ✓ |
| 备份指定相册 | ✓ | N/A |
| 将照片和视频下载到设备 | ✓ | ✓ |
| 多用户支持 | ✓ | ✓ |
| 创建相册与共享相册 | ✓ | ✓ |
| 可拖动的滚动条 | ✓ | ✓ |
| RAW 格式支持 | ✓ | ✓ |
| 元数据查看(EXIF、地图) | ✓ | ✓ |
| 按元数据、物体、人脸、CLIP 搜索 | ✓ | ✓ |
| 管理功能(用户管理) | ✗ | ✓ |
| 后台备份 | ✓ | N/A |
| 虚拟滚动(长列表流畅滚动) | ✓ | ✓ |
| OAuth 支持 | ✓ | ✓ |
| API 密钥 | N/A | ✓ |
| LivePhoto / MotionPhoto 备份与播放 | ✓ | ✓ |
| 360° 全景图像浏览 | ✗ | ✓ |
| 用户自定义存储结构(Storage Template) | ✓ | ✓ |
| 公开(Public)分享 | ✓ | ✓ |
| 归档与收藏夹 | ✓ | ✓ |
| 全球地图 | ✓ | ✓ |
| 伙伴共享(Partner Sharing) | ✓ | ✓ |
| 人脸识别与人脸分组 | ✓ | ✓ |
| 回忆/时光机(X 年前) | ✓ | ✓ |
| 离线支持 | ✓ | ✗ |
| 只读模式画廊(Guest 分享) | ✓ | ✓ |
| 照片堆叠(Stacking) | ✓ | ✓ |
从矩阵中可以提炼出三条关键设计取向:
- 移动端承担“采集端”职责:打开 App 自动备份、后台备份、指定相册备份、离线支持、LivePhoto/MotionPhoto 备份这些都是移动端独占能力(N/A 标记),符合手机作为照片主要来源的定位;
- Web 端承担“管理与浏览端”职责:用户管理等管理功能、API 密钥、360° 全景浏览仅 Web 端提供;
- 核心库能力双端对齐:去重、RAW、EXIF、多模态搜索(元数据/物体/人脸/CLIP)、人脸分组、回忆、地图、分享体系在两端均可用。
3.1 服务端能力印证:核心功能对应的源码模块
功能矩阵中的每一项能力,在仓库 server/src/services/ 目录下都有对应的服务模块,可以据此确认其服务端实现位置:
- 回忆/时光机:memory.service.ts 负责按时间维度(如“X 年前”)聚合素材;移动端对应 memory.service.dart 与时光机页面 memory.page.dart;
- 伙伴共享:partner.service.ts 实现双向订阅式的伙伴共享关系(区别于单次共享链接);
- 公开/只读画廊:共享链接相关能力由共享链接与访问仓库支撑,如 access.repository.ts 等;
- API 密钥:api-key.service.ts 对应矩阵中“仅 Web 端”的 API 密钥能力,也是 Python 文件上传指南 等进阶集成所依赖的入口;
- 重复检测:duplicate.service.ts 支撑“防止文件重复”条目;
- 全球地图:map.service.ts 为地图视图提供地理数据;
- OCR 文本搜索:ocr.service.ts 对接 machine-learning 服务,使 CLIP/OCR 搜索条目落地;
- 用户自定义存储结构:storage.core.ts 按 Storage Template 配置生成素材在磁盘上的目录结构(如
year/、shootTimeDate/),文档见 storage-template.mdx; - OAuth 登录:oauth.controller.ts 与 oauth-login.ts 实现 OAuth 认证流程,配置文档见 oauth.md。
3.2 360° 全景浏览的 Web 端实现
矩阵中“360° 图像浏览仅 Web 端支持”这一条,在 Web 源码中有明确对应:PhotoSphereViewerAdapter.svelte 使用 Photo Sphere Viewer 组件渲染全景素材。从源码结构看,该能力被封装在素材查看器(asset-viewer)适配层中,仅注册于 Web 端查看器,因此移动端矩阵中标记为“Não”(不支持)。
四、部署架构:四个容器与关键环境变量
README 文档将安装指引指向官方文档(本仓库 docs/docs/install/docker-compose.mdx),仓库根目录的 docker/docker-compose.yml 定义了完整的服务拓扑,共 4 个容器:
| 服务 | 镜像 | 职责 |
|---|---|---|
immich-server |
ghcr.io/immich-app/immich-server |
NestJS 主服务(API、任务队列调度、缩略图等),对外暴露 2283 端口 |
immich-machine-learning |
ghcr.io/immich-app/immich-machine-learning |
Python ML 服务(CLIP、人脸识别、OCR、分类),模型缓存放于命名卷 model-cache |
redis(实际为 Valkey) |
valkey/valkey:9 |
任务队列与缓存,healthcheck 使用 redis-cli ping |
database |
ghcr.io/immich-app/postgres:14-vectorchord… |
内置向量扩展的定制 PostgreSQL 镜像,启用 --data-checksums |
几个部署要点(均来自 compose 文件内注释):
- 镜像版本:使用当前 release 对应的 compose 文件与
IMMICH_VERSION,main分支的 compose 可能与最新 release 不兼容; - 硬件加速:ML 服务可通过镜像 tag 追加
-[armnn, cuda, rocm, openvino, rknn]之一启用加速;视频转码加速通过extends引入 hwaccel.transcoding.yml(可选nvenc, quicksync, rkmpp, vaapi, vaapi-wsl),ML 加速同理有 hwaccel.ml.yml,对应文档 ml-hardware-acceleration.md; - 数据库位置:
DB_DATA_LOCATION挂载到/var/lib/postgresql/data,官方提示数据库不支持放在网络共享盘;若数据库位于 HDD 而非 SSD,可取消DB_STORAGE_TYPE: 'HDD'注释以调整存储参数。
4.1 最小 .env 配置
仓库提供 example.env 作为环境变量模板,核心字段与含义如下(与 environment-variables.md 保持一致):
# 上传文件的存储位置
UPLOAD_LOCATION=./library
# 数据库文件存储位置(不支持网络共享)
DB_DATA_LOCATION=./postgres
# 时区(TZ 标识符),取消注释后修改
# TZ=Etc/UTC
# Immich 版本,可固定到具体版本
IMMICH_VERSION=v3
# postgres 连接密码:应改为随机强密码,仅允许 A-Za-z0-9
DB_PASSWORD=postgres
# 以下值无需修改
DB_USERNAME=postgres
DB_DATABASE_NAME=immich
注意事项:DB_PASSWORD 必须仅包含字母与数字(无特殊字符和空格);UPLOAD_LOCATION 与 DB_DATA_LOCATION 分别对应 compose 中 ${UPLOAD_LOCATION}:/data 与 ${DB_DATA_LOCATION}:/var/lib/postgresql/data 两个挂载点,修改位置只需改 .env,不要编辑 compose 挂载行。
五、国际化与社区
README 中“Traduções”(翻译)章节将翻译工作指向官方文档(仓库内对应 translations.md),并列出全部可用语言版本链接。在仓库层面可以验证:
- 翻译文件集中存放于 i18n/ 目录,包含 90+ 语言文件(
en.json、zh_Hans.json、zh_Hant.json、pt.json、ja.json等),本文所依据的 README_pt_BR.md 即其中葡萄牙语(巴西)版本的项目简介; - 移动端与 Web 端 UI 文案均由这些 JSON 文件驱动,翻译贡献流程详见 translations.md。
此外,文档还包含社区活动徽章、Star 历史与贡献者墙等社区区块(指向外部托管图表服务),属于项目社区运营信息,与技术使用无直接关系,此处不再展开。
六、小结
以 README_pt_BR.md 为代表的多语言 README 是理解 Immich 能力版图的最快入口:29 项功能的双端支持矩阵划定了“移动端负责采集备份、Web 端负责管理与高级浏览”的职责分工;docker/ 目录的四容器拓扑与 .env 模板给出了可复制的最小部署形态;而 server/src/services/、web/src/lib/、mobile/lib/ 下的对应模块则为矩阵中每一条能力提供了可追溯的源码依据。部署前建议先体验演示环境,再按 docker-compose 安装指南 结合 environment-variables.md 完成本地化配置。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0624
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00

