63 lines
5.9 KiB
Markdown
63 lines
5.9 KiB
Markdown
# 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。
|
||
|
||
```sh
|
||
# 仅检查候选配置;不会启动应用。
|
||
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:
|
||
|
||
```sh
|
||
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 规则;本次没有删除。
|
||
|
||
实际部署回执和照片库统计应私下保管,不提交公共仓库。
|