My Notes on My Server — Self-Hosting Obsidian LiveSync + CouchDB
Self-Hosting Build Guide, Part 13. Once the blog lives on your server, your notes can too.
← Previous: Part 12 — Backing Up to a NAS Every Night (tar+ssh)
→ Next: Part 14 — A Hands-Off Server (cron)
TL;DR
- Obsidian’s official Sync is a monthly subscription — sync your notes to a database on your own server for $0 plus data ownership
- How: the Self-hosted LiveSync plugin ↔ CouchDB (a Docker container), real-time and bidirectional
- Always bind CouchDB to
127.0.0.1only — beware Docker’s habit of opening it on0.0.0.0 - Reach it only from your own devices: inside a private network (a VPN mesh), never on the open internet
- War story: the culprit behind
ERR_SSL_PROTOCOL_ERRORwasn’t the certificate — it was “no server running behind it”
1. Why Self-Host Instead of Official Sync
Obsidian is a note app, and to see the same notes on multiple devices you need sync. Official Sync works well but it’s a monthly subscription. And your notes pass through someone else’s server.
You already have a server running for the blog, so you can put note sync on top of it.
| Item | Official Sync | Self-hosted LiveSync |
|---|---|---|
| Cost | monthly fee | $0 (your server) |
| Data location | company server | your server |
| Setup effort | flip a switch | configure yourself |
| Sync | fast | real-time, bidirectional |
The price is “configure yourself.” Set it up once and it’s as smooth as the official option after that.
2. The Shape — Plugin ↔ CouchDB
CouchDB is a database good at exchanging changes in real time. The LiveSync plugin pushes to CouchDB whenever a note changes, and other devices pull from it.
flowchart LR
PC[Laptop Obsidian] -->|changes| DB[(CouchDB / your server, Docker)]
Phone[Phone Obsidian] -->|changes| DB
DB -->|sync| PC
DB -->|sync| Phone
3. Never Open It on 0.0.0.0
This is the most important part. Spin up CouchDB with plain Docker and its port opens on 0.0.0.0 (every network interface). Now another device on the same Wi-Fi — even something past a misconfigured router — can reach your database.
ports:
- "5984:5984" # dangerous: 0.0.0.0, exposed on every interface
- "127.0.0.1:5984:5984" # safe: only the computer itself
Bind to 127.0.0.1 only and it’s invisible from outside the server. So how does your phone connect? Only from inside a private network (a VPN mesh). Build a virtual LAN that links just your own devices, and expose CouchDB over https only within it. To the whole internet it stays private.
4. War Story — ERR_SSL_PROTOCOL_ERROR
After finishing the setup I opened the https address and the browser spat out ERR_SSL_PROTOCOL_ERROR. Naturally I assumed it was a certificate problem and stared at certificates for a long time. It wasn’t.
The real cause was simple: the CouchDB container itself wasn’t running. The https front end was set up, but with no server behind it to answer, the TLS connection never completed and the browser reported an “SSL error.”
Lesson: an “SSL error” isn’t always about the certificate. Split the front end (address, cert) from the back end (the actual server), and check the back end is alive first. A quick curl against the backend port settles it in five seconds.
In One Line
You can bring note sync onto your own server too — the LiveSync plugin + CouchDB means $0 in subscription. Just bind CouchDB to 127.0.0.1 and reach it only over a private network. And when you hit ERR_SSL_PROTOCOL_ERROR, suspect a dead back end before the certificate.

Leave a Reply