LiveSync 專用資料庫(系統資料庫 single_node 模式會自動建立)
需求背景
需要一套跨所有裝置(macOS、Windows、Linux、iOS)的 Obsidian vault 同步方案。
最終同步架構:
全裝置 ←— LiveSync (HTTPS) —→ CouchDB (Lima VM)
↓
Caddy (HTTPS 反向代理)
↓
Tailscale 內網 (WireGuard 加密)
iCloud 同步不可行原本計畫 iOS 走 iCloud、電腦端走 LiveSync,Mac mini 作為中樞橋接兩邊。但實測發現 LiveSync 插件是全域同步的,無法在單一裝置上關閉——只要 vault 啟用了 LiveSync,所有開啟該 vault 的裝置都會參與同步。因此無法讓 iOS 只走 iCloud 而不走 LiveSync,必須統一用 LiveSync 同步所有裝置。
這也意味著 HTTPS 是必要的,因為 Obsidian mobile 強制要求加密連線。已透過 Caddy + Tailscale HTTPS 憑證解決。
環境概覽
| 項目 | 規格 |
|---|---|
| 主機 | macOS (你的主機) |
| 虛擬化 | Lima VM (default), Ubuntu 25.10, x86_64 |
| 容器工具 | nerdctl v2.2.1 + nerdctl compose(非 Docker) |
| VM 資源 | 4 CPU / 4GB RAM / 100GB Disk |
| 內網 | Tailscale (你的 tailnet) |
| 反向代理 | Caddy 2 (alpine),提供 Tailscale HTTPS 終止 |
部署架構
macOS (你的主機)
└─ Lima VM (default, Ubuntu 25.10 x86_64)
└─ nerdctl compose
├─ Caddy 2 (alpine) — :443 TLS 終止,host network mode
│ └─ Tailscale HTTPS 憑證 (Let's Encrypt)
│ └─ reverse_proxy → 127.0.0.1:5984
└─ CouchDB 3.5.1 — :5984
└─ Lima port forward: 0.0.0.0:443, 0.0.0.0:5984
部署流程
1. 建立目錄
Lima VM 內 macOS 掛載 /Users/your-name 是唯讀(virtiofs ro),所有可寫資料必須放在 Linux 本地路徑:
limactl shell default -- bash -c "mkdir -p /home/your-user/couchdb/etc /home/your-user/couchdb/data"
limactl shell default -- bash -c "mkdir -p /home/your-user/caddy/certs /home/your-user/caddy/data /home/your-user/caddy/config"
踩坑:Lima 的 HOME 目錄
~/在 Lima shell 中解析到/Users/your-name(macOS 掛載),是唯讀的。必須明確使用/home/your-user/路徑。
2. CouchDB docker-compose.yml
路徑:/home/your-user/couchdb/docker-compose.yml
services:
couchdb:
image: docker.io/library/couchdb:3
restart: unless-stopped
ports:
- "5984:5984"
environment:
- COUCHDB_USER=`你的帳號`
- COUCHDB_PASSWORD=`你的密碼`
volumes:
- ./data:/opt/couchdb/data
- ./etc:/opt/couchdb/etc/local.d
3. CouchDB 設定檔
路徑:/home/your-user/couchdb/etc/local.ini
[couchdb]
single_node=true
max_document_size = 50000000
uuid = your-generated-couchdb-uuid
[chttpd]
require_valid_user = true
max_http_request_size = 4294967296
enable_cors = true
bind_address = 0.0.0.0
[chttpd_auth]
require_valid_user = true
[httpd]
WWW-Authenticate = Basic realm="couchdb"
bind_address = 0.0.0.0
enable_cors = true
[cors]
origins = app://obsidian.md,capacitor://localhost,http://localhost
credentials = true
headers = accept, authorization, content-type, origin, referer
methods = GET, PUT, POST, HEAD, DELETE
max_age = 3600
[admins]區塊CouchDB 啟動後會自動在
local.ini寫入[admins]區塊,將明文密碼轉為 PBKDF2 hash。這是正常行為,不需要手動修改。
設定重點:
single_node=true:單節點模式,不需要叢集max_document_size = 50000000:50MB,LiveSync 附件同步需要max_http_request_size = 4294967296:4GB- CORS 開啟:LiveSync 從 Obsidian App 直連 CouchDB 需要
4. 啟動 CouchDB
limactl shell default -- bash -c "cd /home/your-user/couchdb && nerdctl compose up -d"
5. 建立資料庫
curl -X PUT 'http://`你的帳號`:`你的密碼`@127.0.0.1:5984/your-sync-db'
密碼含特殊字元密碼中的
/在 URL 裡要編碼為%2F。
踩坑:資料庫名稱限制LiveSync 插件的 DB name 欄位不支援
-和_符號。原本取名my-sync-db和my_sync_db都失敗,最終用yoursyncdb。
Caddy 反向代理(HTTPS)
為什麼需要反向代理?
- Obsidian mobile(iOS/Android)的 LiveSync 強制要求 HTTPS
- LiveSync 插件無法在個別裝置關閉,iOS 也必須用 LiveSync,所以 HTTPS 是必要的
- CouchDB 本身不支援 HTTPS
- Caddy 作為 Lima VM 的統一反向代理,未來新增服務(Vaultwarden 等)只要改 Caddyfile
Tailscale HTTPS 憑證
Tailscale 內建 Let’s Encrypt 憑證簽發,不需要自簽憑證:
# 在 macOS 上產生憑證
tailscale cert node.example.ts.net
# 複製到 Lima VM
limactl copy node.example.ts.net.crt default:/home/your-user/caddy/certs/
limactl copy node.example.ts.net.key default:/home/your-user/caddy/certs/
憑證有效期Tailscale 憑證約 90 天有效,需定期重新執行
tailscale cert並複製到 Lima VM。
Caddy docker-compose.yml
路徑:/home/your-user/caddy/docker-compose.yml
services:
caddy:
image: docker.io/library/caddy:2-alpine
restart: unless-stopped
network_mode: host
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile:ro
- ./certs:/etc/caddy/certs:ro
- ./data:/data
- ./config:/config
為什麼用 network_mode: host?Caddy 和 CouchDB 在不同的 compose 專案裡。用 host network 讓 Caddy 直接使用 VM 的網路堆疊,可以透過
127.0.0.1:5984連到 CouchDB,未來加任何服務都能直接連到。
Caddyfile
路徑:/home/your-user/caddy/Caddyfile
{
auto_https off
}
node.example.ts.net:443 {
tls /etc/caddy/certs/node.example.ts.net.crt /etc/caddy/certs/node.example.ts.net.key
handle_path /couchdb/* {
reverse_proxy 127.0.0.1:5984
}
}
設定說明:
auto_https off:關閉 Caddy 自動 HTTPS,因為我們手動管理 Tailscale 憑證handle_path /couchdb/*:將/couchdb/路徑的請求反向代理到 CouchDB,並自動去除/couchdb前綴- 未來新增服務,在此檔案加新的
handle_path區塊即可
啟動 Caddy
limactl shell default -- bash -c "cd /home/your-user/caddy && nerdctl compose up -d"
擴充範例(未來加 Vaultwarden)
node.example.ts.net:443 {
tls /etc/caddy/certs/node.example.ts.net.crt /etc/caddy/certs/node.example.ts.net.key
handle_path /couchdb/* {
reverse_proxy 127.0.0.1:5984
}
handle_path /vaultwarden/* {
reverse_proxy 127.0.0.1:8080
}
}
Lima Port Forward 設定
~/.lima/default/lima.yaml(約第 507 行):
portForwards:
- guestPort: 443
hostIP: "0.0.0.0"
- guestPort: 5984
hostIP: "0.0.0.0"
修改後需重啟 Lima VM(容器設定了 restart: unless-stopped,重啟後會自動恢復):
limactl stop default && limactl start default
驗證:log 中看到以下兩行即成功:
Forwarding TCP from [::]:443 to 0.0.0.0:443Forwarding TCP from [::]:5984 to 0.0.0.0:5984
LiveSync 插件設定
安裝
Obsidian → Settings → Community plugins → Browse → 搜尋 “Self-hosted LiveSync” → Install → Enable
初始設定流程
- 選擇 Minimal setup(不是 Use a Setup URI)
- 填入連線資訊:
- URI:
https://node.example.ts.net/couchdb(全裝置通用,含 mobile) - 或
http://localhost:5984(本機直連,僅限同一台電腦) - Database:
yoursyncdb - Username:
你的帳號 - Password:
你的密碼
- URI:
- E2EE:不啟用(見下方說明)
- Internal API:啟用(效能較好)
- 同步模式:啟用 LiveSync(即時 P2P 雙向同步)
多裝置設定
- 主力機(第一台):Rebuild Everything → 選「I am setting up a new server for the first time / I want to reset my existing server」
- 其他裝置:等主力機同步完 → Rebuild Everything → 選「My remote server is already set up. I want to join this device」
- 其他裝置的 vault 內容跟主力機差不多 → 選「The files in this Vault are almost identical to the server’s」
初次同步
- 首次會把整個 vault 推送到 CouchDB(1000+ 筆記、20000+ chunks)
- 出現 “Do you want to send all chunks before replication?” → 選 Yes
- 資源消耗:CPU 167%、RAM 125MB、網路進 55.8MB(同步完成後降至 CPU 6%、RAM 115MB)
踩坑:Fetch Remote Configuration Failed首次設定時會報 “Could not fetch configuration from remote”,這是正常的。因為新資料庫裡還沒有任何設定檔。直接跳過繼續。
踩坑:Broken files detected同步過程中偵測到壞檔案會阻止同步。先選 “Check it later” 讓整體同步跑完,之後回來處理壞檔案即可恢復正常。
E2EE 的教訓
不建議啟用 E2EE曾經啟用 E2EE(含 Obfuscate Properties),結果遇到嚴重問題:
- 多裝置解密失敗:第三台裝置即使 passphrase 完全一致,仍報 “Decryption with HKDF failed on Path”
- 特定檔案加解密出錯:大檔、含特殊字元的檔名、二進位附件容易觸發
- 關閉 E2EE 需要全部重來:清空資料庫、所有裝置重新同步
結論: 走 Tailscale 內網已有 WireGuard 加密,傳輸安全性足夠,不需要再疊一層 E2EE。關閉 E2EE 後同步速度明顯提升,也更穩定。
清空資料庫重建流程(關閉 E2EE 時用到)
# 刪除並重建
curl -X DELETE 'http://`你的帳號`:`你的密碼`@127.0.0.1:5984/yoursyncdb'
curl -X PUT 'http://`你的帳號`:`你的密碼`@127.0.0.1:5984/yoursyncdb'
# 清除廢棄資料庫
curl -X DELETE 'http://`你的帳號`:`你的密碼`@127.0.0.1:5984/my-sync-db'
curl -X DELETE 'http://`你的帳號`:`你的密碼`@127.0.0.1:5984/my_sync_db'
# 驗證
curl 'http://`你的帳號`:`你的密碼`@127.0.0.1:5984/_all_dbs'
# 預期:["_replicator","_users","yoursyncdb"]
然後主力機 reset server,其他裝置 join。
同步架構決策
為什麼不用 Cloudflare / Linode?
Tailscale 內網 + Caddy HTTPS 已經能讓所有裝置(含 mobile)互通,走內網延遲低、免費、憑證自動簽發。不需要公網部署。
為什麼 HTTPS 是必要的?
原本以為電腦端用 HTTP、iOS 走 iCloud 就好,不需要 HTTPS。但因為 LiveSync 插件無法在個別裝置關閉,iOS 也必須用 LiveSync 同步,而 Obsidian mobile 強制要求 HTTPS,所以 HTTPS 變成必要設定。
iCloud 方案已放棄
iCloud + LiveSync 不能共存原本計畫讓 Mac mini 同時走 iCloud 和 LiveSync,iOS 單獨走 iCloud。但 LiveSync 是 vault 層級的插件,無法在個別裝置上單獨關閉同步。一旦 vault 啟用 LiveSync,所有裝置都必須參與。因此 iCloud 同步已完全放棄,全部改走 LiveSync + Tailscale HTTPS。
所有裝置都必須裝 LiveSync
LiveSync 是同步型插件,vault 內啟用後所有開啟該 vault 的裝置都會同步。包括 iOS 也必須安裝並設定 LiveSync,連線到 HTTPS endpoint https://node.example.ts.net/couchdb。
LiveSync 也支援 S3?
是的,可用 AWS S3、MinIO、Cloudflare R2 等替代 CouchDB。但目前用 CouchDB 走 Tailscale 內網免費且快速,沒有必要換。
nerdctl vs Docker
Lima VM 使用 nerdctl(containerd 前端),非 Docker。個人用途完全足夠:
- 功能與 Docker 幾乎一致,compose 也支援
- 免費、無授權限制(Docker Desktop 商業用要付費)
- CouchDB 這類標準 image 跑起來沒有任何差異
- 資源消耗極低:閒置時 CPU < 6%、RAM 約 115MB
nerdctl stats 注意事項
nerdctl stats --no-stream在 Lima VM 中偶爾會卡住不退出,累積殭屍進程吃 CPU。如果 load average 異常飆高,用ps aux | grep 'nerdctl stats'檢查並 kill。
連線資訊
LiveSync 插件填入(全裝置通用)
| 項目 | 值 |
|---|---|
| URI | https://node.example.ts.net/couchdb |
| Database | yoursyncdb |
| Username | admin |
| Password | 你的密碼 |
iOS / mobile 裝置必須先開啟 Tailscale VPN 才能連到
node.example.ts.net。
服務位置
| 項目 | 值 |
|---|---|
| CouchDB 位置 | Lima VM /home/your-user/couchdb/ |
| Caddy 位置 | Lima VM /home/your-user/caddy/ |
| CouchDB 版本 | 3.5.1 |
| HTTPS URI | https://node.example.ts.net/couchdb |
| HTTP URI(本機直連) | http://localhost:5984 或 http://100.115.83.44:5984 |
檔案結構總覽
/home/your-user/
├── couchdb/
│ ├── docker-compose.yml
│ ├── data/ # CouchDB 資料
│ └── etc/
│ └── local.ini # CouchDB 設定
├── caddy/
│ ├── docker-compose.yml # network_mode: host
│ ├── Caddyfile # 反向代理設定
│ ├── certs/ # Tailscale TLS 憑證
│ │ ├── node.example.ts.net.crt
│ │ └── node.example.ts.net.key
│ ├── data/
│ └── config/
├── nginx-proxy-manager/ # 舊,未使用
└── zoraxy/ # 舊,未使用
待處理
- 多裝置同步鏈路完整測試(全裝置透過 LiveSync HTTPS 同步)
- Tailscale HTTPS 憑證自動更新機制(目前手動,90 天到期)
MCP 設定備忘
此次也處理了 Claude Code 的 MCP 設定:
- 移除 Todoist MCP:
claude mcp remove todoist(從~/.claude.json移除) - 新增 Obsidian MCP (stdio):
claude mcp add --transport stdio obsidian -- node /Users/your-name/mcp-obsidian/dist/index.js --stdio - MCP server 定義要放在
~/.claude.json(按 project 路徑分區),不是~/.claude/settings.json settings.json只放權限、effort level 等設定,不放 MCP server- Vault 路徑:已從 iCloud 改為
/Users/your-name/Obsidian Vault/個人筆記庫(設定檔:~/.obsidian-mcp.json)