Dropping Obsidian Sync for Syncthing: What I Learned Setting Up a Headless Linux Sync Hub
Obsidian Sync costs up to $120 a year if you're on Sync Plus, and paying monthly. That's the number that made me actually do something about it.
I was curious about using Obsidian Sync because people generally were happy that it worked. At least people on reddit were. However I did not want yet another subscription. As much as I like the work that Obsidian do, I just couldn't justify it.
I went with Syncthing because it's peer-to-peer (no third-party server holding my files), it's free, and I've read several threads and watched a few YouTube videos where people swear by it. My always-on NucBox (Ubuntu 24.04, headless) acts as the hub. Windows desktop and Android phone sync to it. I genuinely forget it's there most of the time.
This post isn't a tutorial. The Syncthing docs are fine. What I kept running into was the specific problem of configuring a headless Linux machine without a browser, and nobody really spelled that part out clearly. So here's my setup, including the bits I had to figure out myself.
Getting to the Web UI
Most Syncthing guides assume you can just open localhost:8384 in a browser on the same machine running Syncthing. My NucBox doesn't have a browser. Or a screen. It's just a small fanless PC sitting under my desk running Ubuntu without a Desktop environment.
My first thought was to install a VNC server or something. I wasn't a fan of that approach and after some more time Googling around I eventually found the SSH tunnel approach, which is way simpler than I expected.
Syncthing's web UI runs on port 8384 on the NucBox. I mapped that to a local port on my Windows machine over SSH:
ssh -L 9384:localhost:8384 luke@<nucbox-ip> -N
Then opened localhost:9384 in my browser on my desktop. Syncthing defaults to no auth on the web UI, and I didn't love the idea of an unauthenticated interface accessible over the network. However given this was all running on localhost, I figured that was a problem for another day.
I was already running Syncthing on Windows, which was using port 8384. That's why I mapped to 9384 instead. Anything unused works.
What I Ran on the NucBox
Three commands:
sudo apt install syncthing
systemctl --user enable syncthing
systemctl --user start syncthing
After those, I checked the service was actually running with systemctl --user status syncthing. Active and running. That was my "okay, it's alive" moment.
Actually, one thing I assumed I'd have to deal with. systemctl --user services on a headless machine don't survive logout unless you enable "lingering." Without it, Syncthing stops the second you close your SSH session. I checked mine:
loginctl show-user luke | grep Linger
Turns out it was already enabled (Linger=yes). I'm guessing something during the Ubuntu install set it up — I definitely never ran loginctl enable-linger myself. But if yours shows Linger=no, you'll need:
loginctl enable-linger luke
This is probably the most headless-specific gotcha in the whole setup. And I suspect a lot of guides skip it because they assume you have a desktop login session.
The Ubuntu package is fine. I didn't need any third-party repos.
Once the tunnel was up it was the standard Syncthing workflow. I added a folder, pointed it at my vault, and shared it with my other devices. I installed Syncthing-Fork on Android from the F-Droid store. Paired devices using the Device ID from Actions → Show ID.
The Android app can scan a QR code from that same screen, which is much easier than typing out a 60-character device ID by hand. It can also discover other Syncthing devices on the same network, which was super useful for me.
The .stignore Thing
I'd been running Syncthing for maybe a day when I started seeing orange warning triangles in the UI. Low-level conflicts on .obsidian/workspace.json and .obsidian/workspace-mobile.json. Nothing catastrophic, but it was noise I didn't need.
Turns out Obsidian rewrites those files every time you open it — they store open tabs, cursor positions, that kind of thing. Different on every device, changing constantly. No wonder Syncthing was confused.
A bit of searching told me about .stignore. I added this at the root of the vault:
.obsidian/workspace.json
.obsidian/workspace-mobile.json
.trash/
The rest of .obsidian/ (plugins, themes, settings) syncs fine. That's the stuff I actually want consistent across machines.
A Few Weeks In
On the same LAN it syncs in seconds. Over the internet it handles NAT traversal automatically. I didn't have to configure any port forwarding or open firewall ports. The NucBox isn't running ufw, so there was nothing to touch there. It just worked.
Syncthing apparently used to use relay servers for this, but they were removed a while back (I think around v1.27). Whatever it's doing now, I didn't have to think about it.
I've had this running for a few days now across the NucBox, my Windows desktop, and my Android phone. I haven't thought about it once since setting it up, which is exactly what I wanted.
The $120 a year I was considering paying Obsidian Sync? Going toward something else now.