Immich 机器学习镜像默认上报遥测:v3.3.6 的紧急回退与 v3.4 候选版演进
1. 概述
2026-11-04,Immich 在同一天发布了稳定线的 v3.3.6 与候选线的 v3.4.0-rc.2。v3.3.6 的发行说明只有一段:onnxruntime 在近期版本中默认开启了遥测,机器学习容器会自动向 Microsoft 发送匿名指标数据,现已关闭并为此致歉。
这次改动没有接口变化、没有数据库迁移,也不影响任何功能路径,容易被当作噪音略过。但它触及一个更普遍的问题:容器的外联行为可能由依赖的构建默认值决定,部署方没有做任何显式配置就继承了它。以下以该补丁为线索,说明默认值从哪来、如何确认是否真的关闭、出站边界如何收敛。
时间线:
| 版本 | 发布日期 | 性质 | 与本文相关的内容 |
|---|---|---|---|
| v3.3.5 | 2026-10-21 | 稳定补丁 | 遥测仍默认开启 |
| v3.4.0-rc.1 | 2026-10-30 | 候选 | 安全修复集中批次 |
| v3.3.6 | 2026-11-04 | 稳定补丁 | 仅关闭 ORT 遥测 |
| v3.4.0-rc.2 | 2026-11-04 | 候选 | 纯缺陷修复,含同一遥测修复 |
| v3.4.0-rc.3 | 2026-11-06 | 候选 | 移动端通行密钥、模型修订 v2 |
2. 默认值从哪来
onnxruntime(下称 ORT)自 1.29.0 起,Linux 构建默认向 mobile.events.data.microsoft.com 上报遥测。上报内容包含一个持久设备 ID,以及操作系统、CPU、内存、执行提供者(execution provider)等运行环境信息。Immich 的机器学习镜像直接使用该依赖,未在镜像层关闭,于是每次安装都会带着一个稳定的设备标识持续外联。
三点需要明确:
- 这不是 Immich 自己写的埋点。 发行说明的表述是 “we missed that onnxruntime enabled telemetry by default in a recent release”,性质属于依赖升级带来的默认行为变化。
- 无需任何配置即生效。 只要镜像内加载了 ORT,上报就会发生,与是否启用智能搜索、人脸识别无关。
- 纯 CPU 部署同样受影响。 上报不依赖 GPU,执行提供者只是上报字段之一。
3. 修复的落点
该修复只修改机器学习镜像,服务端代码未动。两处改动:
| 位置 | 改动 | 作用 |
|---|---|---|
| 镜像构建 | 编译 openvino 轮子时加 --no_telemetry |
该轮子不编译遥测路径 |
| ML 包初始化 | os.environ.setdefault("ORT_DISABLE_TELEMETRY", "1") |
进程启动前注入默认值 |
使用 setdefault 而不是直接赋值是有意设计:部署方若显式设置 ORT_DISABLE_TELEMETRY=0,仍可重新开启,默认值不覆盖显式配置。该语句位于包初始化阶段,早于 worker 加载 ORT,因此变量在运行期真正生效,而不只是写进镜像元数据。
这里有一处容易误判:构建参数只覆盖镜像内自编译的 openvino 轮子,其余轮子依赖运行时环境变量。核查必须同时看「变量是否生效」和「进程是否真的外联」,只查其中一条会得到错误结论。
4. 核查方法
一组实际运行 v3.3.5 的部署,容器环境里能看到模型缓存相关变量,但没有 ORT_DISABLE_TELEMETRY:
docker inspect immich_machine_learning \
--format '{{range .Config.Env}}{{println .}}{{end}}' | grep -E 'ORT_|MACHINE_LEARNING_'
# MACHINE_LEARNING_MODEL_ARENA=false
# MACHINE_LEARNING_CACHE_FOLDER=/cache
升级到 v3.3.6 后应能读到 ORT_DISABLE_TELEMETRY=1。再确认进程侧的实际值:
docker exec immich_machine_learning \
python -c 'import immich_ml, os; print(os.environ.get("ORT_DISABLE_TELEMETRY"))'
最后做出站观察。触发一次智能搜索或人脸任务,同时在宿主机抓 DNS:
sudo tcpdump -ni any -vv 'udp port 53' | grep -i 'events.data.microsoft.com'
判定口径:
- 变量为
1且抓包无该域名解析:修复生效; - 变量为
1但仍出现解析:多半来自另一个依赖的遥测,需逐层排查; - 变量缺失:镜像未包含修复,回到版本核对。
5. 出站边界的处置顺序
围绕这次事件的处置顺序如下,不建议用环境变量去补旧镜像:
- 先升级到含修复的版本。 稳定线
v3.3.6,候选线v3.4.0-rc.2及以上。 - 显式声明变量。 即便镜像已有默认值,也写入 compose,便于审计与迁移时复查:
services: immich-machine-learning: environment: ORT_DISABLE_TELEMETRY: "1" - 限制容器出站。 该容器只需访问 server 与模型缓存;缓存目录默认
/cache,可挂到宿主持久卷:
首次拉取模型需要外网,之后可改为按需放行或走内部镜像源。volumes: - ./modelcache:/cache - 合规要求更严时按网段默认拒绝。 在宿主防火墙上对容器网段做默认拒绝、按域名或端口放行,比逐个容器开关更可控。
ML 镜像持有整库的读取路径,其外联风险不只是隐私,还包括数据出境与供应链异常。把它当成「无需关注的后台容器」是常见误区。
6. 同批版本的其他变更
按主线归纳,候选线在这几天内积累的变更如下:
| 主线 | 版本 | 内容 | 部署方要注意什么 |
|---|---|---|---|
| 依赖与隐私 | v3.3.6 / rc.2 | 关闭 ORT 遥测 | 全量部署受益,无需配置 |
| 认证 | rc.1 / rc.3 | 通行密钥:Web 端先落地,rc.3 补齐移动端 | 依赖 HTTPS,可作密码之外的补充 |
| ML 内存 | rc.3 | 提示设置 MACHINE_LEARNING_MODEL_REVISION=v2 |
优化需显式开启,否则仍用旧模型修订 |
| 搜索与 OCR | rc.2 | 编辑与缩略图重建后保留 OCR 文本;只接受合法 ISO 值 | 影响按文本检索的命中率 |
| 移动端 | rc.2 | iOS 显示 10-bit HEIC/AVIF;MOTION PHOTO 提取前校验视频范围 | 上传与预览路径 |
| 稳定性 | rc.2 | 修复 OAuth 回归、人物页 WebSocket、Web worker 导入 | 跟进候选版前必看 |
rc.1 的安全修复批次(共享链接元数据裁剪、插件 allowedHosts 锚定、EXIF 模板变量清洗、不跟随符号链接等)数量最多,已在早前的版本解读中单独梳理,此处不重复。
7. 升级与回滚判定
- 稳定线:
v3.3.5 → v3.3.6。该提交只触及 ML 镜像构建与包初始化,服务端代码未变,可只重建 ML 容器;按惯例把两个镜像版本号一起 pin 也无额外风险。 - 候选线:不建议生产直接跟
v3-rc浮动标签。若要提前验证,用独立 compose、按 digest pin,并保留旧镜像。 - 回滚:ML 镜像按 digest 回滚即可;本次改动不涉及数据库 schema 与模型缓存格式,回滚后无需清理
/cache。 - 闸门:任何重建之前先做数据库转储并校验压缩包完整性,再拉取新镜像。
8. 运维清单
- 记录当前 server 与 ML 的 tag 与 digest,写进变更单;
- 保留旧镜像 digest,不要执行
docker image prune; - 触发数据库转储并用
gzip -t校验; - 更新版本并重建,等待两个容器进入 healthy;
- 核验
ORT_DISABLE_TELEMETRY与包内默认值; - 触发一次人脸或搜索任务,确认模型加载正常;
- 抓包复核出站,一周内保留旧镜像以备回滚。
- 点赞
- 收藏
- 关注作者
评论(0)