← Zakee's Planet

用Syncthing同步我的文件

2023年2月5日 ·

一直以来我都是用OneDrive跨设备同步文件,得益于和Windows系统的深度集成,OneDrive在两台Windows电脑互相同步的时候效果十分完美,可是一旦需要同步的设备不是Windows,就比较难受了。

OneDrive的问题 #

我的博客的Markdown源文件是放在OneDrive上的,平时写完文章,就运行服务器上的一个Shell脚本,大概流程如下图,首先用Rclone同步最新的文章数据到服务器上,然后触发一个Deno脚本,删除所有的草稿文件1,最后打包成压缩文件,丢进Caddy的root目录。这样一来Vercel就可以直接通过http下载文件后完成博客的部署了。

原来的博客部署流程

原来的博客部署流程

OneDrive没有官方的Linux客户端,有第三方的客户端我也没有尝试过,一直用的都是Rclone,而Rclone没有实时同步的功能。对于博客文章的源文件来说,如果你一个月都不写博客、不修改,那这个文件夹的内容就完全不会变,如果设置一个定时同步,就感觉没什么必要。而且,一般写好了一篇新博客,肯定是想马上就发布,所以还得手动触发,不会去等定时同步。所以以上流程虽不是太完美,我也没有觉得太麻烦。而OneDrive真正让我觉得非常不方便的就是其在Windows以外的平台编辑并同步Markdown文件的体验了。

首先说说Android端。官方客户端根本就没有Markdown编辑功能,只能查看渲染出来的效果(而且还不支持中文字体,全是框框)。除此之外,它似乎就没有文件夹同步的功能,我想要把OneDrive上的一个文件夹与Android文件系统中的一个文件夹保持同步都实现不了,还要借助第三方软件比如FolderSync、OneSync等才可以。

其次,我一直都希望有一个可以临时编辑博客文章的Web端。然而,OneDrive的网页版在国内已经无法正常访问。由于需要临时编辑博客文章的时候一般用的都不是自己常用的设备,这就意味着我们可能无法科学上网,因此这个需求就无法实现或者非常麻烦。

想想我当初把文章全部移到OneDrive上的一个重要原因就是想要在各个平台无缝编辑并同步,而这样的使用体验只能说离差强人意还差点。正好最近在寻找Logseq同步的方案,看到大家都推荐用Syncthing,就尝试了下,果断就换了。

什么是Syncthing #

Syncthing是一个开源免费跨平台的P2P文件同步工具。由于是基于P2P技术,所以它是去中心化的。所有的文件都不会存储在第三方系统中,而且设备与设备间的通讯都经过TLS加密,所以是非常私密且安全的。

请设想以下场景:我有一台Windows电脑和一台Android手机,连的是同一个WiFi,如果用OneDrive同步,我在电脑上修改了文件,文件需要先上传到OneDrive服务器,然后手机再从OneDrive服务器上下载。即使两台设备位于同一个局域网中,也需要像这样绕一个大圈。如果改用Syncthing同步,则电脑与手机就能直接走局域网同步,不仅同步速度更快,更摆脱了对第三方服务依赖。

当电脑和手机不在一个局域网时候,在发现服务器的协助下,它们会尝试广域网直连或者经中继服务器同步。发现服务器和中继服务器都可以自己部署,官方和社区都有贡献公共节点可用。使用公共的中继服务器同步的话速度会比较慢,Syncthing会不断尝试直连,直到连接上为止。另外,大家可能会担心同步经过中继服务器是否会有隐私泄露的风险,实际上,中继服务器传送的只是加密后的文件,任何第三方都没办法获取文件的真正内容,中继服务器只知道连接设备的ID以及其IP地址。

使用Syncthing #

Syncthing本身是一个命令行软件,运行后浏览器访问http://localhost:8384/即可打开自带的web管理界面,一般推荐使用一个wrapper程序来方便程序的开机启动并在系统托盘添加一个图标。Windows上官方推荐的是SyncTrayzor,不过我自己用的是Syncthing Tray。软件的安装使用都非常简单,官方文档很好而且网上也有很多教程,所以这里不再赘述。需要注意的是系统防火墙要允许Syncthing的连接,而且路由器要开启UPnP2

Android端有官方app,直接下载安装,然后打开两个设备的web管理界面,在一个设备上添加另一个设备的ID,并选择要共享的文件夹,然后在另一台设备上选择同意,连接成功之后就可以同步了。文件是直接同步到设备的文件系统中,所以我可以自由使用各种软件来查看、编辑我的文件,不管是博客文章的Markdown,还是Logseq的图谱。

如果我们只需要简单的文件同步,这样其实就足够了。不过有一个问题:想要同步,两台设备必须同时都在线。所以为了随时随地都能够同步 ,我们需要有一台设备能一直开着Syncthing,没错,我们在云服务器或者NAS上也跑一个Syncthing就行了。可直接用Docker部署,docker-compose.yml配置如下,更详细的指引可参考:Docker Container for Syncthing

version: "3"
services:
  syncthing:
    image: syncthing/syncthing
    container_name: syncthing
    hostname: my-syncthing
    environment:
      - PUID=1000
      - PGID=1000
    volumes:
      - /wherever/st-sync:/var/syncthing
    network_mode: host
    restart: unless-stopped

在云服务器上部署Syncthing后,云服务器同时也充当一个备份节点的角色,可以开启版本控制。另外我们还可以结合File Browser这样的Web文件管理器实现一个真正意义上的自托管同步云盘。前面提到我一直希望终于有一个web界面来临时编辑博客,而OneDrive又有种种不方便,现在,我在File Browser的根目录中建一个子目录,作为Syncthing的同步文件夹,就能通过File Browser网页端直接编辑Markdown文件,然后实时同步了。

以下视频展示了在File Browser中编辑页面后保存、Syncthing检测到文件更改后完成同步、Hugo检测到本地文件变更后重新渲染页面,并触发浏览器刷新的过程。服务器与本地是通过广域网TCP直连的,这个流程用了十多秒,不算快,不过也没有必要很快。

有了Syncthing与File Browser这套组合,我的博客部署流程又能优化一下了。现在不管任何时候Vercel需要部署博客都可以通过File Browser的api直接取得content.tar.gz打包文件,再也不用操心文章数据是否已经先同步好了。这个下载链接是不公开的所以不用跑那个删除草稿的脚本,而为了公开没有草稿版本的content.tar.gz,目前我还是单独设置了每天凌晨3点定时更新,这次才会删除草稿。大家可以访问我的公共文件目录,下载博客文章的源码。

这篇文章只是简单分享下我对Syncthing的用法以及使用体验,更多功能大家可自行探索,个人认为Syncthing是关于个人文件同步方面很好的解决方案了,还是非常值得一试的。


  1. 脚本已经分享在GitHub Gist上,写这个脚本主要是因为我希望把博客的Markdown源文件分享出来,但又不想让别人看到我的草稿。😅 ↩︎

  2. Universal Plug and Play(通用即插即用),一般路由器都会默认开启。当本地网络需要和公网建立对等访问的时候,可以借助UPnP自动映射端口出去。 ↩︎