服务卡片 · 文件与存储
Syncthing:三台机器上始终一致的那个文件夹
有一类文件需要同时存在于好几台机器上,而且不需要历史:家庭文档目录、笔记目录、以及进 Immich 之前的手机照片暂存区。Syncthing 让这些内容在机架、两台笔记本和一部手机之间保持一致,中间没有一台持有权威副本的服务器——正是这个特性让它和 Nextcloud 截然不同。
| 容器镜像 | syncthing/syncthing:1.29.2 |
|---|---|
| 宿主端口 | :8384/tcp, :22000/tcp |
| 数据目录 | /srv/homelab/syncthing/data |
| 内存预留 | 210 MB |
| CPU 上限 | 0.40 vCPU (cpus: "0.40") — hashing on a large first sync is the peak |
| 更新节奏 | twice a year, pinned tag. Protocol changes are backward compatible within reason, but the database format upgrades in place and does not downgrade |
| ARM 兼容 | arm64 native; file watching works and does not need the slower polling mode on a modern kernel |
| 宿主 | 容器 | proto | 暴露 | 用途 |
|---|---|---|---|---|
| :8384 | 8384 | tcp | 仅局域网 | web UI, used mostly to read the sync state and pause folders |
| :22000 | 22000 | tcp | 仅局域网 | the sync protocol itself, between the rack and the laptops |
部署步骤
按你打算长期使用的 PUID 建好两个目录
首次同步之后再改 uid,会留下容器写不了的文件,表现为某个文件夹永远卡在 95%。
run sudo mkdir -p /srv/homelab/syncthing/{config,data} sudo chown -R 1000:1000 /srv/homelab/syncthing在加入任何对端之前先设好界面密码
网页界面首次启动时没有任何认证。在文件夹列表里还是空的时候就到「设置 -> 图形界面」里设好用户名和密码。
run cd /srv/homelab/syncthing && docker compose up -d # 打开 http://192.168.10.20:8384 -> 设置 -> 图形界面 -> 设用户名和密码手工交换设备 ID,并添加那三个文件夹
自动发现很方便,但它也是不请自来的对端申请同步的方式。要从另一台机器的界面上复制 ID,而不是接受弹出的第一个请求。
run # 每台笔记本:操作 -> 显示 ID,复制那串长字符串 # 机架上:添加远程设备 -> 粘贴,然后逐个文件夹显式共享
Syncthing 还是 Nextcloud,人们常把这两个搞混
Nextcloud 是一台客户端连接的服务器;服务器上有一份,客户端是它的视图。Syncthing 没有服务器:每台设备都持有完整副本,它们互相交换「谁的版本更新」。
实际差别在出故障时显现。机架挂了,Nextcloud 就挂了,所有客户端都卡住。用 Syncthing,两台笔记本之间照常同步,机架回来之后再追上。代价是每台设备都要占磁盘,以及两台机器离线编辑同一份文档时会出现冲突文件。
| Syncthing | Nextcloud | |
|---|---|---|
| 权威副本 | 没有,所有对端平等 | 服务器 |
| 机架离线 | 笔记本之间照常同步 | 所有人都卡住 |
| 磁盘成本 | 每台设备一份完整副本 | 只有服务器一份完整副本 |
| 冲突 | 出现 sync-conflict 文件 | 服务器按时间戳裁决 |
| 与外人分享 | 加对方设备 ID | 建用户和分享链接 |
三个文件夹,以及为什么不再多
household(真正重要的文档:保险、租约、家电说明书)、notes(否则只存在于某个人脑子里的那些 markdown)、staging(进 Immich 并从手机上删掉之前的照片)。
其它一切都刻意不同步。代码走 git,媒体走 NAS,备份只单向。每往 Syncthing 里加一个文件夹,就是每台设备多占一块磁盘,外加出冲突时多一个要想的东西。
错峰版本保留才是救命的那个功能
关掉版本保留时,一台设备上的删除会在几秒内同步到所有设备,文件处处消失。错峰版本保留会在机架上留住三十天的旧版本,把最常见的那种灾难——有人整理文件夹然后整理错了——变成一件无关紧要的小事。
.stversions 目录就在文件夹旁边,且被排除在同步集之外,所以不会传播。每月看一下它的大小;在文档目录上它一直很小,但在它变成 20GB 之前就该知道它存在。
# 文件夹 -> 编辑 -> 文件版本控制 -> 错峰
# 保留 30 天,清理间隔 3600 秒
# 然后:du -sh /srv/homelab/syncthing/data/household/.stversionscompose 文件
整份文件放在 /srv/homelab/syncthing/compose.yaml。标签固定版本号,不用 latest——树莓派上回滚比升级麻烦得多。
services:
syncthing:
image: syncthing/syncthing:1.29.2
container_name: syncthing
restart: unless-stopped
ports:
- "8384:8384/tcp"
- "22000:22000/tcp"
- "22000:22000/udp"
environment:
TZ: Asia/Shanghai
PUID: "1000"
PGID: "1000"
STGUIADDRESS: 0.0.0.0:8384
volumes:
- /srv/homelab/syncthing/config:/var/syncthing/config
- /srv/homelab/syncthing/data:/var/syncthing/data
networks: [rack]
networks:
rack:
external: true加固清单
- 网页界面设有密码,且只在局域网可达;同步端口从不做转发
- 设备 ID 手工交换而不是靠自动发现,没有不请自来的对端能请求同步
- 文件夹清单刻意保持很小:这是文档同步工具,不是备份目标
- 共享文档目录启用了错峰版本保留,误删在三十天内可以取回,不需要恢复备份
备份方案
同步的文件夹本身在别处都有副本,所以这里不备份文件夹内容——NAS 会各自独立地复制它们。要备份的是 Syncthing 的配置和数据库,因为重建一个 200GB 文件夹的索引要几个小时,而重建设备 ID 意味着每一台对端都要重新接受一次。
上线后验证
- 笔记本上新建的文件在几秒内出现在机架和另一台笔记本上
- 在一台设备上删除文件,能从机架上的 .stversions 里恢复出来
- 机架上的网页界面显示三个对端都已连接,文件夹状态是「已同步」而不是「同步中」
- 暂停文件夹、在两台机器上编辑同一文件、再恢复,结果是恰好一个冲突文件,而不是丢失一次编辑
踩过的坑
- 同步一个同时又是备份任务目标的目录,会造出一圈互相触发的改动。让同步集和备份集保持分离,或者显式排除备份暂存区。
- 容器以你设定的 PUID/PGID 写入。首次同步之后再改这两个值,会留下容器写不了的文件,表现为某个文件夹永远卡在 95%。
- 设备 ID 很长,容易抄错。要从网页界面复制,而不是从聊天消息里复制;并且要把旧设备条目删掉,而不是让它们永远处于暂停状态。
- Syncthing 不是备份,它自己的文档也这么说。版本保留能缓解删除;它挡不住那种在所有设备上把所有文件都加密的勒索事件。
硬件与选型问答
- Syncthing 能替代 NAS 吗?
- 不能,它也没打算这么做。Syncthing 让几台都在使用中的设备之间保持工作副本一致;NAS 负责归档和版本历史。两者只在暂存目录上有重叠,而且即便是那里,最终接收副本的也是 NAS。
- 在局域网里够快吗?
- 大文件时它能跑满 Pi 4 的千兆链路;而它通常承担的小文档负载,瓶颈往往在首次建索引时的哈希计算而不是传输。200GB 的首次同步要几个小时,之后的同步是秒级。
- 手机怎么办?
- 安卓版可以自动同步一个照片目录,暂存目录就是为此存在的。iOS 版受平台后台规则限制更多,所以在 iOS 上实用的做法是手动同步笔记目录,而不是自动上传照片——照片这件事,Immich 的 App 做得更好。