What is Syncthing?
Syncthing is a continuous file synchronisation program that keeps folders in sync between your computers, phones and servers without a cloud provider in the middle. It is open source under the MPL-2.0 license, encrypts every connection with TLS, and authenticates devices by cryptographic IDs. Running it on an always-on server gives your other devices a sync partner that is always reachable.
Requirements
- Any Linux server or NAS with 1 vCPU and 512 MB of RAM. Large folders with many files need more RAM for the index.
- Docker Engine and Docker Compose v2.
- Disk space for every folder you plan to sync.
Step 1: Prepare the server
This guide assumes Ubuntu 24.04 with Docker installed. If you need Docker, follow the official install guide. Create a folder and note your user and group IDs so synced files are owned by you:
mkdir -p ~/syncthing/data && cd ~/syncthing
id -u && id -g
Step 2: Create the Docker Compose file
Save this as docker-compose.yml, using the official syncthing/syncthing image:
services:
syncthing:
image: syncthing/syncthing:2
container_name: syncthing
hostname: my-syncthing
restart: unless-stopped
environment:
PUID: 1000
PGID: 1000
TZ: "Europe/London"
volumes:
- ./data:/var/syncthing
ports:
- "127.0.0.1:8384:8384"
- "22000:22000/tcp"
- "22000:22000/udp"
- "21027:21027/udp"
healthcheck:
test: curl -fkLsS -m 2 127.0.0.1:8384/rest/noauth/health | grep -o --color=never OK || exit 1
interval: 1m
timeout: 10s
retries: 3
Set PUID and PGID to the values from Step 1. The hostname becomes the device name other Syncthing devices see. Everything lives in ./data: the configuration and keys in config/, and your synced folders anywhere under /var/syncthing inside the container, for example /var/syncthing/Documents.
The GUI port 8384 is bound to 127.0.0.1 because a fresh Syncthing GUI has no password. Ports 22000 and 21027 stay public so devices can connect. Those connections are always TLS-encrypted and only accepted from device IDs you approve. There are no secrets to generate in the Compose file. The 2 tag follows the latest Syncthing 2.x release.
Step 3: Start and open the app
docker compose up -d
ssh -L 8384:127.0.0.1:8384 user@YOUR_SERVER_IP
Run the SSH tunnel from your own computer, then open http://localhost:8384. Syncthing warns that no GUI password is set. Go to Actions, Settings, GUI, set a username and a strong password, and save. Then pair a device: open Actions, Show ID on one device, and on the other click "Add Remote Device" and paste the ID. Accept the request on the first device, share a folder, and choose its path, such as /var/syncthing/Documents.
Step 4: Put it behind HTTPS
If you want the GUI on a domain rather than through an SSH tunnel, put a reverse proxy in front of 8384. With Caddy:
sync.example.com {
reverse_proxy 127.0.0.1:8384 {
header_up Host {upstream_hostport}
}
}
The Host rewrite is needed because Syncthing's GUI rejects requests whose host header does not match, as protection against DNS rebinding attacks. Make sure the GUI password is set before you expose it. The sync ports do not go through the proxy.
Backups and upgrades
Back up ./data/config: it contains config.xml, cert.pem and key.pem. The key pair is your device identity, and losing it means re-pairing every device. The synced data itself is copied on your other devices, but Syncthing is not a backup, since deletions sync too. Enable "File Versioning" (staggered or trash can) on important folders, and keep an independent backup.
Upgrade with:
docker compose pull && docker compose up -d
The Docker image disables Syncthing's built-in auto-upgrade, so pulling the image is the update path.
Troubleshooting
- Devices connect only through relays and sync is slow: port 22000 TCP/UDP is not reachable. Open it in your firewall and forward it on your router.
- Local devices are not discovered: discovery uses UDP 21027 broadcasts, which do not always cross Docker's bridge network. Add the server by address (
tcp://SERVER_IP:22000) or usenetwork_mode: host. - "Host check error" through a proxy: rewrite the
Hostheader to the upstream, as shown above. - Permission denied on synced files:
PUIDandPGIDdo not match the owner of the folders on the host.
Next steps
Add your phone with a community client (the official Android app was retired in 2024, and forks such as Syncthing-Fork continue it; on iOS, Möbius Sync is a paid option), configure ignore patterns with .stignore, enable file versioning on critical folders, and mark the server as an "introducer" to simplify adding new devices.
Spotted something out of date? Tell us and we will update the guide.