N.16 · 开发 · 2026.11.06 · 约 22 分钟

不买 Obsidian Sync,我怎么让笔记在Mac、Windows、服务器和浏览器之间同步

坚果云负责两台电脑,Git 负责历史,Syncthing 和 SilverBullet 负责自托管副本与网页端。三条链路都经过 Windows,每条只做一件事。

我的 Obsidian 库里有 500 多篇 Markdown:几个独立产品的需求和架构文档、学习计划,还有家用服务器的运维记录。平时会在这些地方用到它:

  • Windows 台式机:主力开发机,大部分笔记在这里写,AI 编程助手也在这里读写文档。
  • Mac:外出时用。
  • 浏览器 / 手机:临时查资料,或者随手改一句。

同时我还希望:所有修改都能找回历史版本,数据不只放在一家云服务里。

Obsidian 官方的 Sync 能解决多端同步,但满足不了后两个要求,所以我用免费工具和自己的服务器搭了一套。下面的设置都在三端实际核对过,数据截至 2026 年 11 月 6 日。

整体架构:以 Windows 为中心

文件在哪里在哪里编辑
GitHub私有仓库完整版本历史 · 异地备份
Windows · 中心主力机Obsidian · 唯一的 Git 仓库
MacObsidian外出时用
家用服务器自托管副本/srv/obsidian/vault
SilverBullet网页版编辑器直接读写 vault
浏览器 / 手机随时打开不用装 Obsidian
  1. 01Mac ↔ Windows坚果云 · Obsidian 插件两台电脑都能用 Obsidian 编辑
  2. 02Windows → GitHubGit · obsidian-git版本历史和异地备份
  3. 03Windows ↔ 服务器Syncthing + SilverBullet自托管副本和网页端编辑
FIG.01 · 同步拓扑三条链路 · 全部经过 Windows

三条链路各管一件事,全部经过 Windows,原因放在后面讲。

一、Mac ↔ Windows:坚果云

坚果云支持 WebDAV,在国内外访问都比较稳定。Obsidian 社区里有一个坚果云同步插件 Nutstore Sync,登录后就能把 vault 同步到坚果云的网盘。Mac 和 Windows 都装这个插件,指向同一个远程目录 /docs/。我用的是坚果云免费版:纯文本 vault 体积很小,免费额度完全够用。

Windows 上 Nutstore Sync 插件的设置页:远程目录 /docs/、跳过 30 MB 以上的文件、智能合并、Git 样式冲突标记、同步前确认、每 2 分钟定时同步、宽松模式
FIG.02 · Nutstore Sync 设置Windows 端

Windows 端的关键设置:

远程目录
/docs/
两台电脑指向同一个目录
定时自动同步
每 2 分钟
不开实时同步,减少请求次数和冲突概率
启动后自动同步
第 3 秒
打开 Obsidian 后先同步一次
同步前确认 · 删除前确认
开启
先列出待执行的操作,防止误删被同步到所有设备
冲突解决策略
智能合并
同一文件两边都改时,按文本差异自动合并
Git 样式的冲突标记
开启
合并失败时用 <<<<<<< / >>>>>>> 标出冲突,和处理代码冲突一样
同步模式
宽松
同名且大小相同、但没有同步记录的文件直接跳过,文件多时更快
跳过大文件
> 30 MB
录屏这类大附件不进网盘
排除规则
.git · .obsidian · .trash · .DS_Store
只同步正文
TAB.01 · Windows 端9 项设置

宽松模式很适合我的情况。Windows 上的文件同时还会被 Syncthing 改写,如果用严格模式逐个比对,第一次同步会很慢;宽松模式只处理真正有差异的文件。

排除 .obsidian 是有意的。 Mac 和 Windows 的快捷键、窗口布局和部分插件不一样,把配置也同步的话,两边会互相覆盖。

排除 .git 更重要。 Git 仓库只放在 Windows 上,Mac 不需要它。如果坚果云同步 .git 目录,两边同时写索引文件时很容易把仓库弄坏。

Mac 端:只做坚果云同步的终端

Mac 上的 vault 放在 ~/Documents/docs,同样装 Nutstore Sync 插件(v1.2.1),用坚果云账号扫码登录。和 Windows 对照,同步相关的设置几乎一致:

远程目录
留空(显示为 /)
实际相同,见下文
定时自动同步 · 实时同步
每 2 分钟 · 关闭
= 一致
启动后自动同步
第 3 秒
= 一致
同步前确认 · 删除前确认
开启
= 一致
冲突解决策略
智能合并 + Git 样式标记
= 一致
同步模式
宽松
= 一致
跳过大文件
> 30 MB
= 一致
配置目录 .obsidian
不同步
= 一致
排除规则
默认规则 + .trash · .claude · .claudian · .omx
多排除了几个 AI 工具目录
TAB.02 · Mac 端9 项里 7 项一致

有几处值得单独说。

远程目录留空也能对上,但最好显式填写。 我翻了插件代码:远程目录为空或只填 / 时,插件会自动改用本地 vault 的文件夹名。Mac 上的文件夹恰好也叫 docs,所以最终同步的就是 /docs/,和 Windows 指向同一处。反过来说,哪天把 Mac 上的文件夹改了名,插件会悄悄换成同步一个新的空目录。更稳妥的做法是两端都直接填 /docs/。

排除规则在插件默认规则上,再加我自己的几项。 默认规则已经覆盖了 .git、node_modules、.DS_Store、__MACOSX 和 Office 的 ~$ 临时文件。我在 Mac 上也会让 Claude Code 这类工具直接读写 vault,它们会在根目录留下 .claude、.claudian、.omx 之类的本地状态目录,这些只留在本机。.trash 也被排除了,所以在 Mac 上删掉的笔记,回收站里的副本只存在于 Mac 本地。

「同步前确认」只对手动同步生效。 定时自动同步不会每次弹窗,只有要删除文件时,才会因为「自动同步删除前确认」停下来等我确认。日常基本无感。

Mac 上没有 Git,也没有 Syncthing。 Mac 端的 vault 不是 Git 仓库,也不连服务器,只和坚果云打交道,其余链路全部交给 Windows。

一次 Mac 上的修改要多久到 Windows

两端都是每 2 分钟同步一次,所以一次 Mac 编辑的传播路径是:

  1. Mac 下一次定时同步时上传到坚果云:最长约 2 分钟;
  2. Windows 下一次定时同步时拉下来:最长约 2 分钟;
  3. Syncthing 把它传到服务器、SilverBullet 可见:几秒;
  4. Windows 上停止变动 10 分钟后,obsidian-git 把它提交到 GitHub。

按设置推算,到达 Windows 最慢约 4 分钟,平均约 2 分钟,前提是两边的 Obsidian 都开着。

我实测了两次:在 Mac 的 vault 里写一个测试文件,再从 Mac 上通过 SilverBullet 读服务器上的同一个文件,看新内容什么时候出现。

123秒

新建文件

Mac 写入 → 服务器上的 SilverBullet 读到

83秒

追加一行

Mac 写入 → Windows 落盘(看服务器上文件的修改时间,Syncthing 会保留 Windows 端的时间)

按设置推算:0–4 分钟平均约 2 分钟实测

FIG.03 · Mac 上的一次修改两次实测都在推算区间里

日常的体感是:在 Mac 上改完,过一两分钟,Windows 和网页端就都能看到了。

二、Windows → GitHub:Git 自动备份

Windows 上的 vault 本身就是一个 Git 仓库,远程是 GitHub 上的私有仓库。自动备份交给 obsidian-git 插件:

obsidian-git 插件的 Automatic 设置:每 10 分钟自动提交并同步、停止编辑后才开始计时、自动 pull 关闭、提交信息使用日期占位符
FIG.04 · obsidian-git 设置Windows 端
  • Auto commit-and-sync interval:10 分钟。
  • Auto commit-and-sync after stopping file edits:开启。计时从停止编辑开始算,正在写字时不会被打断;停笔 10 分钟后,插件把所有改动 commit 并 push 到 GitHub。
  • 不拆分 commit 和 push 的计时,也不只提交已暂存的文件,所以每次都是一次完整快照。
  • 自动 pull 关闭。只有 Windows 会推送这个仓库,没有需要拉取的远程改动。
  • 提交信息固定为 vault backup: {{date}},效果是 vault backup: 2026-11-04 13:49:40。

从 2026 年 5 月开始,已经累积了 580 多次提交。

有了坚果云,为什么还要 Git:

  • 坚果云同步最新状态,Git 保存历史。 一次错误的批量替换会被坚果云原样同步到另一台电脑,Git 却能让我回到任何一次提交。
  • GitHub 是另一家公司的另一份副本。 哪天坚果云账号或家用服务器出了问题,仓库里的数据还在。
  • 方便 AI 协作。 让 Claude Code、Codex 改文档时,它们会写正常的语义化提交信息。最近一个月,自动备份提交 132 次,手动提交 6 次,Git 历史能清楚区分两者。

.gitignore 排除了 .obsidian/、.trash/、AI 工具的本地运行状态、浏览器自动化截图,以及 Syncthing 的 .stfolder/ 和 .stversions/。

三、Windows ↔ 服务器:Syncthing + SilverBullet

为什么还要一台服务器

坚果云和 GitHub 已经覆盖了两台电脑和备份,但我还想要两样东西:

  1. 在任何浏览器里打开笔记,包括手机和公司电脑,不用装 Obsidian。
  2. 一份完全由自己控制的实时副本。

我家里有一台 OptiPlex 小主机,用 Docker 跑着二十多个自托管服务,正好可以承担这件事。

Syncthing:点对点双向同步

Syncthing 是开源的点对点文件同步工具,不经过任何第三方服务器。我的配置:

  • 服务器端:Syncthing 跑在 Docker 里,把 /srv/obsidian/vault 挂进容器,文件夹类型是 Send & Receive。
  • Windows 端:装官方的 WinGet 包,用一个计划任务在登录时后台启动,不弹窗、不开浏览器。
  • 网络:Windows 端关掉全局发现、中继和 NAT 穿透,只通过 Tailscale 内网主动连服务器。同步流量不走公网,也不依赖 Syncthing 的公共中继。
  • 版本保留:两端都开 Staggered File Versioning,保留 180 天。其他设备传来的修改或删除,会先把旧版本存进 .stversions/。服务器上这部分目前占 18 MB。

有一个容易忽略的细节:.stignore 本身不会被同步,Windows 和服务器上要各放一份。我的 .stignore 排除了 .git、.obsidian、.trash、各种 AI 工具目录和坚果云插件日志,服务器上只留纯正文。

SilverBullet:网页端编辑同一份文件

SilverBullet 是一个开源的网页版 Markdown 笔记工具,可以直接把一个目录当笔记库用。关键在于:

Syncthing 和 SilverBullet 挂载服务器上的同一个目录。

# SilverBullet compose(节选)
services:
  silverbullet:
    image: ghcr.io/silverbulletmd/silverbullet:2.11.1
    environment:
      SB_FS_WATCH: auto      # 监听文件系统变化,Syncthing 写入后立即可见
    volumes:
      - ./data:/data                 # 账号、会话等应用状态,放在 vault 之外
      - /srv/obsidian/vault:/vault   # 和 Syncthing 共用同一个目录
    ports:
      - 127.0.0.1:13000:3000         # 只监听本机,对外由 Tailscale / Cloudflare 转发

所以整条链路是双向的:

  • 在 Windows 的 Obsidian 里改一篇笔记 → Syncthing 写入服务器目录 → SilverBullet 立刻看到。
  • 在手机浏览器里用 SilverBullet 改一篇笔记 → 写入服务器目录 → Syncthing 传回 Windows → 下次自动备份进 Git,坚果云同步时再传到 Mac。

几个具体配置:

  • 关掉 SilverBullet 自带的版本功能,免得它在同步目录里再建一个 Git 仓库,和 Windows 上的仓库冲突。
  • 账号数据放在 ./data,不进 vault,也就不会被同步到任何地方。
  • 访问入口有两个:内网走 Tailscale Serve;公网走 Cloudflare Tunnel,前面加一道 Cloudflare Access 邮箱验证码,之后还要过 SilverBullet 自己的登录。
  • SilverBullet 把 vault 根目录的 index.md 当首页。Obsidian 不用这个文件,两边互不干扰。

下面是在手机浏览器里打开 SilverBullet 首页的样子:

手机浏览器里的 SilverBullet 首页:Recent incomplete tasks 列出了这篇文章草稿里的三条待办
FIG.05 · SilverBullet手机浏览器 · 地址栏已打码

首页的「Recent incomplete tasks」会列出整个 vault 里还没完成的任务。图里那三条,是我写这篇草稿时留的待办:在 Windows 上写完,几分钟后手机上就能看到,也能直接勾选。这些任务是 SilverBullet 自己索引出来的,不需要 Obsidian 的任何插件。

上线前的验证

正式接入前,我做了这些检查:

  1. 用 Robocopy 把整个 vault(7,103 个文件,约 152 MiB)完整备份到另一块物理硬盘,再开始首次同步。
  2. 在 Windows 新建一篇 Markdown,确认服务器上的文件 SHA-256 一致。
  3. 在 SilverBullet 里改一篇笔记,确认 Windows 上的文件 SHA-256 一致。
  4. 在 SilverBullet 里删一篇笔记,确认删除会同步到 Windows,并在 .stversions/ 留下可恢复的版本。
  5. 测完删掉测试文件和测试产生的版本。

写这篇文章时我又查了一次:服务器端文件夹状态是 idle,待同步 0、错误 0。Syncthing 面板显示这份 vault 一共 744 个文件、192 个文件夹,约 54.5 MiB;唯一的远程设备是 Windows 端,状态为「最新」。

服务器上的 Syncthing 面板:Obsidian Vault 文件夹为最新,本地共 744 个文件、192 个文件夹、约 54.5 MiB,唯一的远程设备 Windows Obsidian Bridge 为最新
FIG.06 · Syncthing服务器端 · 主机名与设备标识已打码

这篇草稿在 Windows 上保存后,几秒内就出现在服务器上,两边的 SHA-256 完全相同。

四、为什么以 Windows 为中心

这个架构最明显的取舍是:Mac 和服务器之间没有直接同步,所有修改都要经过 Windows。

这样做有三个好处:

  • 一个文件夹最多连两种同步工具。 坚果云和 Syncthing 都只连 Windows,两个同步引擎互相干扰的可能降到最低。
  • Git 只在一个地方。 只有 Windows 有 .git,提交历史只有一个来源,不会出现多台设备同时 push。
  • 每条链路只负责一件事。 出问题时,很容易判断是哪一段没同步。

代价也很明确:

  • Windows 上的 Obsidian 得开着,坚果云插件才会同步,obsidian-git 才会自动提交。Windows 关机时,Mac 的修改只到坚果云,服务器暂时收不到;服务器上的修改只停在服务器,Mac 也暂时看不到。开机后会自动补齐。
  • Windows 同时承担两种同步,冲突处理仍然靠人判断。 我的习惯是同一时间只在一个地方编辑同一篇笔记。实际用下来,Mac 和网页端多半只是查看和小修改,很少遇到冲突。

五、防误删的四层保护

  1. 坚果云的同步前确认、删除前确认传播前

    误操作还没传到其他设备时,先拦下来

  2. Syncthing 文件版本,两端都开180 天

    其他设备传来的修改或删除

  3. Git 提交历史,存在 GitHub 私有仓库全部历史

    任意一次自动备份时的完整状态

  4. 坚果云自身的文件历史按套餐

    网盘端的历史版本,保留多久取决于坚果云的套餐

TAB.03 · 防误删第 1 层拦截,第 2–4 层恢复

所有凭证,包括密码、token 和 Cookie,都不放在 vault 里。它们留在各个服务自己的数据目录或密码管理器中,笔记同步到哪里都不会泄露。

六、成本

  • Obsidian免费
  • 坚果云免费版对纯文本 vault 来说,免费额度完全够用
  • GitHub 私有仓库免费
  • Syncthing · SilverBullet · Tailscale免费开源,或个人使用免费
  • 家用服务器0本来就在运行,没有额外费用

额外支出0 元

TAB.04 · 成本按月计

如果没有家用服务器,只用前两层(坚果云 + Git)也足够覆盖「两台电脑同步 + 版本历史」。服务器这一层,是在这之上加的网页端访问和自托管副本。