Files
pigway-frame-flow/docs/SYNOLOGY_PHOTOS_API.md
T
渡口浪人 dec17aeb1d
Community checks / verify (push) Skipped
Verify Frame Flow / verify (push) Failing after 6m49s
fix: replace vulnerable container bases and release v0.1.21
2026-10-18 19:10:00 +08:00

5.9 KiB
Raw Blame History

Synology Photos API 来源与 Ubuntu 迁移候选

本功能从 NAS 的 Photos API 按需读取照片,不需要 NFS、SMB 或 /photos 文件挂载。NAS 原照片不复制整库到 Server。

已支持与边界

  • 新来源类型 synology-photos,与 local 挂载目录明确分开。
  • 共享空间 SYNO.FotoTeam、当前登录账号的个人空间 SYNO.Foto;不是任意 NAS 用户的个人空间。
  • 人物列表分批读取,照片按 ID 做 any 并集 / all 交集;无匹配时明确为空,不回退全库。
  • 支持目录相对路径、递归开关、日期文件夹 / 标题、方向及现有质量筛选。. 表示所选空间根目录;路径以 Photos 返回的目录名为准,不是 Ubuntu 绝对路径。
  • 图片使用经过实测的 Thumbnail.get v2、size=xl。原始文件名不代表下载的是原图。对 NAS 当前原图下载接口的探测被拒绝,原图下载未宣称支持。
  • 照片枚举 Browse.Item.list v7,人物 Browse.Person.list v3;每批 500 条,最多 100000 条,超过明确失败,界面目录上限仍由 catalog_limit 控制。不支持 NAS 未暴露或账号无权访问的相册。
  • 文件系统 local 来源已停用;旧配置需显式转换为 Photos API 来源。

安全与缓存

保持 HTTPS SHA-256 证书指纹校验,在同一 TLS socket 验证证书后才发送 SID。仅调用固定 API 与只读方法,不使用通用 RPC 转发、不跟随重定向。密码不持久化,会话文件保持 0600。会话过期返回明确重连提示;不保存密码以自动重登,也不对 NAS 原会话发 logout。权限不足与会话失效分开处理。

缓存为 /data/cache/synology-photos,默认总图片字节上限 256 MiB,可用 SYNOLOGY_PHOTOS_CACHE_BYTES 调整(环境配置最小 1 MiB),单张不超过应用 20 MiB 限制。只下载选中的图片。文件锁合并跨线程、跨进程下载,预留容量后写 0600 临时文件,完成长度核对及 Pillow 验证 / 解码后原子提交;超时、中断及无效数据清理临时文件,下次持锁读取清理进程异常退出遗留的 .part。按最近使用淘汰。缓存身份包含端点、会话摘要、空间、照片 ID、索引版本及缩略图缓存键,避免账号 / 空间混用。

容量上限针对图片和下载临时文件的逻辑字节,不含 SQLite、锁文件与文件系统元数据;并发串行缓存锁会等待正在进行的单张下载。网络 socket 超时 30 秒,流读取检查 90 秒期限,已阻塞的单次 socket 读取最多再等待其超时。

Ubuntu 候选配置

在正式 Git 仓库开发;不要把迁移临时解包目录作为开发仓库。

候选文件:deploy/compose.ubuntu-photos-api.yml。内部端口 18787,UID/GID 10333:10333。通过私有环境变量设置 FRAME_FLOW_APP_DIR(已有应用目录)、FRAME_FLOW_ENV_FILE(已有私有配置文件)和可选 FRAME_FLOW_BIND(默认回环地址),不在仓库保存真实主机地址或部署目录。

无 /photos 绑定。create_host_path: false 防止在 T7 未挂载时悄悄创建目录;但仍需在启动前检查 findmnt -T "$FRAME_FLOW_APP_DIR" 的实际源设备。

.env 需从已确认的配置安全迁移,保留 Photos URL、证书 pin 与已有 Frame Flow / 相框鉴权;不要把密钥写入仓库。模板默认 KOKONNA_WRITE_ENABLED=false。创建 data/tmp,属主保持 10333:10333,TMPDIR=/data/tmp。Docker data-root 和 containerd root 也必须在 T7,不能仅检查 bind mount。

# 仅检查候选配置;不会启动应用。
FRAME_FLOW_IMAGE='<已验证的镜像标签>' docker compose -f deploy/compose.ubuntu-photos-api.yml config --quiet

发布统一使用根目录 Dockerfile 完整构建,包含固定基础映像、系统安全更新和锁定依赖,避免继承旧映像中的系统漏洞。

旧来源转换与恢复

停止目标实例、复制数据、转换真实配置及切换部署均需另行授权,本次没有执行。

  1. 确认 T7 挂载,备份 NAS 原有完整 /data、/config、旧镜像及 Compose。SQLite 必须停服务后复制,或使用 SQLite backup API;不要只复制有活动 WAL 的主文件。

  2. 将备份恢复到上述 Server 目录,保持私密文件权限,创建 data/tmp。保留旧 NAS 备份直至切换验收。

  3. 对每个需要摆脱挂载的来源显式 dry run:

    python scripts/migrate-photos-api.py --database /data/frameflow.db --source family
    # 已获授权、目标服务已停止时才执行:
    python scripts/migrate-photos-api.py --database /data/frameflow.db --source family --apply --service-stopped
    

    工具保持来源 ID、任务引用、人物空间、any/all、目录、方向及筛选设置,只修改来源类型并关闭旧本地 @eaDir 预览开关;自动在同一数据目录生成 0600 SQLite 备份。转换不会验证该账号在 Photos 中是否可访问相同目录,必须再做真实只读预览。不要转换确实依赖挂载且 Photos 未收录的目录。

  4. 已获得单独授权后才停旧实例、以只读候选配置启动 Server,并逐个来源验收。没有授权前不执行 compose up 或开启真实写入。

  5. 回退时停止 Server,恢复已备份的数据库和配置(停服务时处理对应 WAL/SHM),恢复旧来源类型与 NAS 原部署,保证只有一个实例有写权限。原 NAS 照片不受缓存或来源转换影响。

NFS 授权判断

API 来源的共享 / 个人空间取图已经可以完全不依赖 NFS,因此这条新取图链路不需要为旧客户端保留 DSM photo NFS 授权。但目前旧来源和待迁移配置没有全部切换验收,不能据此宣称迁移完成或旧本地来源已可脱离挂载。确认没有其他已批准用途后,可以单独授权删除该特定 NFS 规则;本次没有删除。

实际部署回执和照片库统计应私下保管,不提交公共仓库。