← 返回主页

Obsidian 多端实时同步搭建记录

2026-09-06

date: 2026-09-06 tags: [obsidian, livesync, couchdb, 同步, 运维记录] status: 已跑通 version: 脱敏公开版


Obsidian 多端实时同步搭建记录

一句话总结:两台电脑的 Obsidian 通过自建 CouchDB 做双向实时同步,云端存密文数据库,各端本地保留完整 md 文件;最大的坑不是配置,是插件复制被"挂起"需要手动放行。

本文已脱敏:服务器地址、账号、密码、内部库名等敏感信息均以占位符表示,替换为自己的实际值即可复用。


一、架构与原理

组成 说明
服务器 云服务器(我用的是腾讯云轻量),CouchDB 3.4(Docker 容器,端口 5984)
客户端 笔记本 + 台式机,各装 Obsidian + Self-hosted LiveSync v1.0.26
数据形态 云端是 CouchDB 数据库(JSON 文档),不是 md 文件;md 文件只存在各端本地 vault
同步机制 笔记被切成小块(文档 ID 以 h: 开头),双向增量复制,改动秒级推送
加密 端到端加密开启(E2EE v2),服务器上全是密文,截获也读不出来

⚠️ 文件名会被统一小写handleFilenameCaseSensitive: false),如何把Obsidian...md 在云端是 如何把obsidian...md,比对时先转小写。


二、最终配置参数

URI http://<服务器IP>:5984
数据库 <笔记库名>
账号 <同步账号>
密码 <同步账号密码>
端到端加密 开启,两台的 passphrase 必须完全一致
必开开关 LiveSync(实时同步)
建议开 Sync on Start(启动即同步)、Periodic Replication(定时复制)

新设备接入最快方式:在已配好的那台用「复制配置 URI / Copy setup URI」生成 obsidian://setuplivesync?...,新设备打开即完成配置(URI、库名、账号、加密口令一次带全)。 新设备首次动作选 Fetch from remote千万别选"以本地为准重建"——会把云端数据冲掉。


三、踩过的坑与解法(按时间顺序)

# 症状 真实原因 解决办法
1 Obsidian 装插件卡住,只下了 manifest.json 自带下载走 GitHub 不稳,缺 main.js 插件根本不加载 从 GitHub release 手工下载 main.js+styles.css下完核对字节数(网络不稳会截断,curl exit 23)
2 插件装好了没反应 四个自动开关(liveSync/syncOnSave/syncOnStart/periodicReplication默认全 false 至少开 liveSync
3 判断"服务器没有数据" 判据用错:只看了有没有新库名,没看已有库内容 笔记其实写进了已存在的
4 判断"另一台从没连过服务器" 两机在同一家庭宽带下,NAT 后公网 IP 相同,靠 IP 根本区分不了设备 改用 hostname 区分机器 + _local_docs 检查点计数
5 以为云端多出的笔记是另一台传来的 该文档元数据是 "deleted": true,是本机建了又删的 看文档元数据里的 deleted 字段
6 新设备连不上 老账号在 _users 里是 deleted 状态,老设备靠认证缓存硬撑,新设备登录必失败 新建专用同步账号
7 向导报「访问被禁止 / Access forbidden」 向导会试着建数据库(服务器级操作),普通成员账号无权限 见下方"权限三连坑"
8 连上了却不传数据(最坑) 插件处于挂起态,反复读 sync_parameters 却不启动复制 Ctrl+PSelf-hosted LiveSync: Toggle LiveSync

权限三连坑(第 7 条展开)

  1. 账号建好后默认可能无权访问该库——若库的 _security{roles:["_admin"]},必须单独授权: PUT /<db>/_security 里加 members.names: ["<同步账号>"]
  2. 想在 _users 里塞 "roles":["_admin"] 会被拒绝:No system roles (starting with underscore) in users db——系统角色只能写进服务器配置
  3. 账号同时存在于 _users 和 admins 配置时 _users 优先,管理员身份不生效——必须删除 _users 里那条

最终解法:

# 写进 admins 配置
curl -X PUT -u 管理员:密码 http://127.0.0.1:5984/_node/_local/_config/admins/<同步账号> \
  -H 'Content-Type: application/json' -d '"<同步账号密码>"'
# 删除 _users 里的同名记录,否则 roles 仍是 []
curl -X DELETE -u 管理员:密码 \
  "http://127.0.0.1:5984/_users/org.couchdb.user:<同步账号>?rev=<rev>"

四、验收方法(三条硬指标,缺一不可)

指标 命令 / 位置 成功标准
文档总数增长 GET /<db>doc_count 新笔记传上去后变大
设备检查点增加 GET /<db>/_local_docs 每接入一台新设备 +2 条(一推一拉)
出现真实复制 容器日志 _changes / _revs_diff / _bulk_docs

挂起态的典型特征:日志里几十上百次 GET /<db>/_local/obsidian_livesync_sync_parameters但没有任何 _changes/_bulk_docs。看到这个就说明插件在等你放行,不是故障。

最终验收:在其中一台新建一篇测试笔记,另一台本地 vault 里能看到它 = 真正双向打通。


五、排查速查命令

# 本机机器名(区分设备的关键,别信公网 IP)
hostname

# 插件配置状态
cat "<vault>/.obsidian/plugins/obsidian-livesync/data.json" | grep -E \
  '"liveSync"|"syncOnStart"|"isConfigured"|"encrypt"'

# 本地文件清单(比对前统一小写)
find "<vault>" -type f \( -name "*.md" -o -name "*.base" \) -not -path "*/.obsidian/*" \
  -printf "%P\n" | tr 'A-Z' 'a-z' | sort

# 服务器端
docker logs --since 5m <容器名> | grep -cE '_changes|_bulk_docs'   # 有没有真在传
curl -s -u 管理员:密码 http://127.0.0.1:5984/<db>/_local_docs      # 几台设备

六、遗留事项

事项 现状 建议
数据库混用 笔记库与其他项目数据共用一个库 笔记量还小时拆库成本最低;先备份
账号权限 同步账号目前是服务器管理员 跑稳后可降权(降权后不能新建库,日常同步不受影响)
冲突副本 云端有撞名产生的副本文件 直接删
传输安全 5984 明文 HTTP,但内容已端到端加密 稳妥起见可给 5984 套 HTTPS
云端备份 全量导出 JSON 存于服务器 保留作后悔药

七、经验教训

  1. 先确定判据再下结论——今天三次判断失误("服务器没数据""另一台没连过""台式机传上来了"),全部源于用错了判据或只看了表面。
  2. 同网多台机器公网 IP 相同,排查多端问题必须靠 hostname 和服务端检查点。
  3. "没报错"不等于"在同步"——挂起态就完全静默,必须看服务端日志里的 _changes 才算数。