Self hosting Syncthing relay and discover
I spent some time over the Christmas break to work on refining some tasks like exchanging large amounts of data between our two offices. Both sites already have a proper 3-2-1 backup strategy, now we have got an additional copy. A nice to have I wanted was an option to ditch iCloud Drive. Syncthing is not the best or the easiest replacement, but it is workable and has been reliable for three devices I used it on in the past.
One thing I wanted was a private discovery and relay server. While not strictly necessary, it helps with those funny little checkmarks on certain forms you have to fill out where curious customers want to be really sure what happens to their data while we are working with it. (Let us not talk about how valuable these forms are. I cannot fault our customers for using them - it is not (always) their choice.)
Running the services is fairly simple. Download two binaries, punch a hole in your firewall and you are done. Nearly all our services are wrapped in a Docker container. Not because Docker makes things easier or more secure, but it nicely standardises things and I do not have to mess with systemd - what else can you ask for?
Side quest: For some reason Forgejos runners fell apart and I used the opportunity to fix this. I did not bother cleaning up the Git history. There is nothing interesting in there but 15 ways to not do docker-in-docker, giving up and provisioning a bare metal runner.
You can find the repository for the discovery service here and relay service here.
Both services have a current.tar.gz which is the actual binary downloaded from Syncthings release pages. When I find some time I will replace this with getting the source and building it. This isn't about trusting the binary but having a reproducible build not relying on other infrastructure.
There is also a gitea / forgejo / surely Github workflow in there building the image and pushing it to the package registry.
With the Docker images built both services are ran via docker compose. Usually I would specify the network of the reverse proxy caddy_internal and that is it. The relay requires either a Layer 4 proxy or its port directly exposed to the Internet. Technically there are two ports if you want statistics for your relay.
services:
discover:
image: source.rdctd.de/timo/syncthing-discover-docker:latest
restart: unless-stopped
container_name: syncthing_discover
networks:
- caddy_internal
volumes:
- ./discover:/data
relay:
image: source.rdctd.de/timo/syncthing-relay-docker:latest
restart: unless-stopped
container_name: syncthing_relay
volumes:
- ./relay:/data
ports:
- 22067:22067
- 22070:22070
environment:
- TOKEN=superSecretToken
networks:
caddy_internal:
external: true
When starting relay will print a connection string. You have to append &token= plus the value of the TOKEN environment variable to it. The relay is configured to be a private relay. Do not forget to punch a hole for the relay port(s) 22067 in your firewall.
Discover listens on ports 8443 for the actual service and 8444 for metrics. Syncthing has examples how to configure the most common reverse proxies.
Once that is done you are good to go to setup your clients and within a minute or two settling down they should be happy little file syncing apps using your own infrastructure.
posted on Jan. 10, 2026, 8:03 p.m. in Tech Quips, homelab, self-hosting