Docs menu Retired systems

Syncthing

Syncthing 2.1.2 on docker-main as an always-on peer for my Obsidian vault, from 2026-07-22 to 2026-08-06. The capability drop that stopped it starting, the sync alternatives I weighed, and the decommission.

Updated Source in the repo

For two weeks Syncthing kept a second, always-on copy of my Obsidian vault on docker-main, with 90 days of file versions. My Windows PC held the working copy, because Obsidian works from local files, and the two synchronized directly. On 2026-08-06 I decided I didn’t want the service any more and decommissioned it.

ItemValue
VersionSyncthing 2.1.2 on both peers, pinned rather than following a floating tag
Server peerdocker-main, container syncthing, with host networking for LAN discovery
Desktop peerMy Windows PC, installed from WinGet and started at login
Folderobsidian-the-vault, send and receive on both peers
VersioningStaggered, 90 days, on the server only
Excluded files.obsidian/workspace.json and .obsidian/workspace-mobile.json
InterfaceAn internal HTTPS name through Nginx Proxy Manager; only the proxy could reach its port
Deployed2026-07-22
Retired2026-08-06

What it synced

The vault was small: 15 files in six directories, about 6.4 MB, including the .obsidian folder with the Minimal theme and the Kanban and Excalidraw plugins. By the decommission it had grown to 17 files and 9.4 MB, with two archived versions.

I excluded the two workspace files because they hold each device’s interface state and change constantly. Plugins, themes, hotkeys and the rest of .obsidian stayed in sync. Before pairing anything I zipped the vault as a recovery point for its original state.

The peers connected directly across VLANs, from my workstation’s network to docker-main’s, over TLS 1.3, so the firewall needed no change for synchronization. I checked the result with a canonical SHA-256 manifest generated independently on both peers, which matched over the 14 synchronized files. Then I tested the round trip: a small file created on the server arrived on Windows with the same hash, and when I deleted it on Windows, the server removed its live copy and archived the same hash in its version folder.

The capability-drop restart

The first container never started Syncthing at all. I had deployed it with cap_drop: ALL, and it went into a restart loop, reaching restart count 7 and unhealthy without opening any of its listeners. The logs showed why:

chown: /var/syncthing: Operation not permitted
su-exec: setgroups(1000): Operation not permitted

The image’s entrypoint changes ownership of its data directory and then switches to UID and GID 1000, and both steps need capabilities I had dropped. I removed only cap_drop: ALL, kept no-new-privileges:true, and recreated the container from the same image. It came up healthy with a restart count of 0. Because Syncthing never started during the loop, the failed container never scanned or touched the vault.

Obsidian sync alternatives

On 2026-07-27 I wrote up the free and self-hosted alternatives for one ordinary Obsidian vault across computers and phones. The conclusion was to keep Syncthing unless an iPhone or iPad became a normal part of how I edit notes.

The point that settled most of it: installing something on every device isn’t a weakness of Syncthing. Every method needs code on each device to notice a changed file, send it, receive other changes and write them into the local vault. Another product can hide that inside Obsidian, but it can’t remove it.

OptionConflictsHistoryMobileVerdict
SyncthingKeeps a separate conflict file; I merge by handServer versions for 90 daysCommunity clients on Android and iOSBest fit, already deployed
Self-hosted LiveSync and CouchDBMerges simple conflicts and asks about harder onesDatabase revisions, which compaction discardsRuns inside Obsidian everywhereThe best alternative if mobile matters
Remotely Save with WebDAV or S3Detects a conflict and asks which copy to keep; merging is paidDepends on the storage behind itRuns inside Obsidian on Android and iOSA simpler mobile option
Nextcloud desktop syncKeeps a local conflicted copyBuilt-in server versionsMobile apps give file access, not necessarily a local vaultOnly if I wanted a general private cloud anyway
GitThree-way merges, otherwise manualThe best historyThe Obsidian Git plugin calls mobile support unstableBetter as a history layer than as the sync
SeafileKeeps a separate conflict fileServer version controlMobile apps give file accessNo advantage over Syncthing here

Syncthing also kept working when Obsidian was closed, which the plugin-based options can’t: they synchronize only while Obsidian runs, and mobile systems can suspend it in the background.

I set two conditions for reconsidering. If iPhone or iPad editing became normal, I would test Self-hosted LiveSync with CouchDB against a copy of the vault. If I deployed Nextcloud for general file storage anyway, I would test Remotely Save against its WebDAV endpoint, but I wouldn’t deploy Nextcloud for this vault alone. Either way, I wouldn’t run two sync engines against the live vault; LiveSync’s own documentation warns against it, so any trial starts with a separate copy.

Decommission, 2026-08-06

Ten days later I retired it anyway. Syncthing existed so the vault had an always-on second copy and 90 days of versions, and I decided I didn’t want the service any more. I chose to delete the server copy and its version history along with the service, deliberately rather than as an oversight. The vault on my Windows PC was untouched, and Obsidian carried on working from it.

  1. Service and data. docker compose down --rmi all removed the container and its image in one pass. Then I deleted the Compose directory with its configuration and the data directory with the vault copy and versions. Afterwards docker-main had no matching container, image, volume, directory or systemd unit, and nothing listened on Syncthing’s ports.
  2. Monitoring. I removed the Prometheus probe for its HTTPS name and checked the config with promtool. The reload didn’t take, twice. The lifecycle API is disabled, so POST /-/reload returned 403, and the SIGHUP I sent instead changed nothing either: prometheus.yml is a single-file bind mount, and sed -i writes a replacement file rather than editing in place, so the container kept reading the old inode. Recreating the container picked up the new file, and Prometheus ended at 48 of 48 targets up.
  3. Network. I deleted the proxy host through Nginx Proxy Manager’s API and the internal DNS record from UniFi.
  4. Records. The platform folder moved to Archive/ with its Compose file, deployment record, device runbook, the alternatives write-up and the deployment evidence. Its open items, such as pairing a laptop, closed with it.

Note: A sed -i against a single-file bind mount needs a container recreate, not a reload. The same trap had caught me on this Prometheus host on 2026-07-13 and again during the Kasm work on 2026-07-28.

The same day I closed the two follow-ups. A shared UniFi policy let the proxy reach several web interfaces on docker-main. I checked every port in it against the live listeners and removed the two with nothing behind them, Syncthing’s and the one left by Termix, retired on 2026-07-28. The five remaining services still answered through the proxy and their probes stayed green. I archived the stored Syncthing credential rather than destroying it.

Written from the public Homelab repository on GitHub, which records the lab's changes, incidents and current state.