跳转到内容

Syncthing:多设备同步 ​

完成后,NAS 成为你几台设备之间同步文件夹的一个常驻节点:手机、笔记本和 NAS 上的同一个文件夹保持一致,数据点对点传输,不经过第三方云。

适合谁 ​

  • 要在几台设备之间保持某些文件夹一致,比如文档、笔记、手机拍的照片。
  • 不想把数据交给云盘。Syncthing 不上传到云,只在设备之间直接交换。
  • 需要网页分享链接、日历联系人:用 Nextcloud。需要手机相册自动备份和浏览:用 Immich。

同步不是备份

Syncthing 官方的 FAQ 说得很直接:它不是一个好的备份工具,因为对文件的所有改动,包括修改和删除,都会传播到所有设备。在一台设备上误删或者被勒索软件加密,几秒后所有设备都一样。

  • 文件版本默认是关闭的。 开启后,它也只对来自其他设备的改动有效,在本机上直接做的修改,它无法也不会保存旧版本。
  • NAS 上可以开启版本控制,并用「只接收」文件夹,下面会讲,这能让 NAS 成为一道缓冲,但仍然不是备份。
  • 重要的数据,另外做备份,见备份策略:冗余不是备份。

应用信息 ​

项内容
示例清单有 syncthing,示例文件日期 2025-06-01
镜像LinuxServer 的 lscr.io/linuxserver/syncthing:latest,另有官方镜像 syncthing/syncthing
端口8384(网页界面)、22000 的 TCP 和 UDP(同步,UDP 是 QUIC)、21027/UDP(局域网发现)
数据/config 是配置和设备密钥,同步的文件夹是你自己挂进去的目录
官方文档docs.syncthing.net

先决定网络模式 ​

示例用 Docker 默认的桥接网络加端口映射。Syncthing 官方的 Docker 说明指出,这会有问题:Docker 默认的网络模式让 Syncthing 看不到局域网地址,它只能看到容器内部 172.17.0.0/16 网段的地址,局域网里设备之间的直连很可能建立不起来,速度会很差,除非你手动配置设备地址。官方因此强烈建议用 host 网络模式。

host 网络(官方推荐)桥接加端口映射(示例的写法)
局域网发现可用不可用,要在对端手动填 NAS 的地址 tcp://<NAS 的 IP>:22000
端口Syncthing 直接监听 8384、22000、21027,必须保证它们在 NAS 上空闲,compose 里不能写 ports映射哪个用哪个
防火墙Docker 不为 host 网络创建规则,这些端口等于 NAS 自己的端口,OMV 防火墙规则对它们生效,启用了防火墙要放行Docker 的端口映射会绕过宿主机防火墙

选 host 网络。如果必须保持桥接,就在每台对端设备上,把 NAS 这台设备的 地址(Addresses)从默认的 dynamic 改成 tcp://<NAS 的 IP>:22000, dynamic,这是 Syncthing 防火墙文档里给的办法。

网页界面默认监听所有网卡,必须设密码

LinuxServer 镜像里 Syncthing 监听 0.0.0.0:8384,局域网里的任何人都能打开。Syncthing 官方也提醒,对外可达的界面一定要认证,最好开 TLS。

  • 影响范围:没有密码的界面,意味着任何访问到 8384 的人都能添加设备、读写你同步的所有文件夹。
  • 前置条件:第一次打开界面,先设密码,再做别的;8384 不要用路由器转发到公网;22000 只有在你明确要让设备从外网直连时才转发。
  • 怎么回退:在界面设置里设好用户名和密码;删掉路由器上的转发;仍然担心就停止容器。

部署 ​

准备一个放同步内容的共享文件夹,下文叫 sync,专用用户 appuser 对它有读写权限,见容器权限:PUID、PGID 与共享文件夹。

服务 → Compose → 文件(Services → Compose → Files)→ 添加 → 从模板添加,选 syncthing,添加后 编辑。示例原样是:

yaml
services:
  syncthing:
    image: lscr.io/linuxserver/syncthing:latest
    container_name: syncthing
    hostname: syncthing #optional
    environment:
      - PUID=1000
      - PGID=100
      - TZ=Etc/UTC
    volumes:
      - CHANGE_TO_COMPOSE_DATA_PATH/syncthing/config:/config
      - CHANGE_TO_COMPOSE_DATA_PATH/syncthing/data1:/data1
      - CHANGE_TO_COMPOSE_DATA_PATH/syncthing/data2:/data2
    ports:
      - 8384:8384
      - 22000:22000/tcp
      - 22000:22000/udp
      - 21027:21027/udp
    restart: unless-stopped

改成 host 网络的版本:

yaml
services:
  syncthing:
    image: lscr.io/linuxserver/syncthing:latest
    container_name: syncthing
    hostname: syncthing
    network_mode: host
    environment:
      - PUID=${{ uid:"appuser" }}
      - PGID=${{ gid:"users" }}
      - TZ=${{ tz }}
    volumes:
      - ${{ sf:"appdata" }}/syncthing/config:/config
      - ${{ sf:"sync" }}:/data1
    restart: unless-stopped
  • network_mode: host:ports 整段删掉,Compose 规范不允许两者同时存在。
  • 配置放 appdata;同步目录直接挂 sync 共享文件夹,容器里叫 /data1,以后在界面里添加文件夹,路径填 /data1。需要同步多个目录,就多挂几行,比如 /data2。
  • host 模式下,插件的 服务 → Compose → 端口 页看不到它的端口,因为那里只汇总 compose 文件里写出来的映射。上线前先在 OMV 的 shell 里(root)运行 ss -tulpn | grep -E ":8384 |:22000 |:21027 ",确认没人占用这三个端口。

点 保存,检查,上线。

首次设置 ​

  1. 浏览器打开 http://<NAS 的 IP>:8384。
  2. 先设密码:Actions → Settings → GUI(操作 → 设置 → GUI),填用户名和密码。LinuxServer 的说明也是这么建议的。
  3. 在 Actions → Show ID 里能看到这台设备的设备 ID。其他设备添加它时要用。
  4. 在手机或电脑上装 Syncthing,添加 NAS 的设备 ID。NAS 的界面里会提示有新设备想连接,点接受。
  5. 共享文件夹时,在两边都添加。Syncthing 会交换文件信息,已经存在的文件不会重复传输,第一次对齐要一会儿。

文件夹类型 ​

类型行为用在
发送和接收(Send & Receive)默认,双向同步每台设备都会改的文件夹
仅发送(Send Only)忽略其他设备的改动,只发出本机的改动本机是「标准副本」,比如手机相册
仅接收(Receive Only)应用来自其他设备的改动,但本机的修改不会传出去NAS 上的镜像、备份落点

手机拍的照片同步到 NAS,常见做法是手机端「仅发送」、NAS 端「仅接收」。注意手机上删除照片,删除仍会同步到 NAS,所以 NAS 端要开版本控制。界面里的文字以你的 Syncthing 版本为准。

文件版本 ​

在文件夹的设置里找 文件版本控制(File Versioning)。默认是关闭,没有旧版本被保留。

方式说明
回收站(Trash Can)被删除或被覆盖的文件放进回收站,可设置保留天数,0 表示不自动清理
简单(Simple)保留最近 N 个旧版本
分阶段(Staggered)越旧的版本保留得越稀,到最长保留天数就删,0 表示永远保留
外部(External)交给你自己的脚本处理

旧版本放在同步文件夹里的 .stversions 子目录,会占空间,也会被通过 SMB 访问这个共享的人看到。自定义版本路径时,要和同步文件夹在同一个文件系统上。

忽略规则 ​

不想同步的文件,在同步文件夹根目录放一个 .stignore 文件,也可以在文件夹设置里编辑。.stignore 本身不会被同步,第一个匹配的规则生效,以 // 开头的行是注释:

text
// 系统生成的垃圾文件,前缀 (?d) 表示它们挡住目录删除时允许一并删掉
(?d).DS_Store
(?d)Thumbs.db
// 临时文件
*.tmp
// 以 / 开头只匹配根目录
/cache

检查结果 ​

  1. 打开界面时要求密码。http://你的公网IP:8384 在手机流量下打不开。
  2. NAS 和其他设备互相显示为已连接。在 NAS 上点开那台设备,连接类型应当是局域网(LAN)直连,而不是中继(Relay)。
  3. 在手机的同步文件夹里放一个测试文件,几秒后出现在 NAS 的 sync 共享文件夹里。
  4. 在手机上删掉它,NAS 端的文件也被删,并且在 sync 里的 .stversions 中出现了旧版本(版本控制生效)。
  5. 在 OMV 的 shell 里(root)运行 ls -ln,同步下来的文件属主是 appuser 的 UID。

备份与维护 ​

  • 配置目录(appdata/syncthing/config)里有这台设备的密钥,它决定了设备 ID。丢了的话,设备 ID 会变,所有设备都要重新配对。它不大,插件的计划备份会包含它,备份时容器会被停止,同步会暂停一下。
  • 同步的内容本身要另外备份,见rsync 任务。Syncthing 不是备份,上面已经说过。
  • 升级:拉取新镜像,重建容器。大版本升级前先备份配置目录,并看 Syncthing 的发布说明。

常见问题 ​

同在一个局域网,同步却很慢。 多半是桥接网络下局域网直连没建立,走了中继。改成 host 网络,或者手动填 tcp://<NAS 的 IP>:22000。

容器起不来,或者 8384、22000 打不开。 host 模式下端口直接用宿主机的,被占用就起不来。用 ss -tulpn 查。

文件夹显示「Out of Sync」或者权限错误。 目录属主和 PUID、PGID 对不上,见容器权限。

同步目录里出现很多 .stversions 和冲突文件。 版本控制和冲突副本的正常行为。定期清理,或者把版本保留时间调短。

参考资料 ​

OpenMediaVault 非官方中文使用指南,与 openmediavault 项目及其开发者无隶属关系。