VPS Tutorials
Syncthing on a VPS (2026): Docker, Cross-Device File Sync, Versioning and Security Configuration
Deploy Syncthing v2.1.3 on a VPS with Docker Compose, configure device pairing, cross-device file sync, folder modes, version retention, .stignore, WireGuard, port 22000, backup and restore, and common troubleshooting.

If you regularly copy the same set of files between a computer, phone, NAS and VPS, you will soon run into three problems: which copy is the latest, whether deleting a file by mistake will delete it everywhere, and how to connect securely over the public internet. Syncthing exists to let multiple devices sync files directly, without depending on any one cloud drive provider.
Deploying Syncthing on a VPS gives you a sync node that is online around the clock. When your laptop is off, your phone can still sync files to the VPS first; when another computer comes online, it can then pull the latest content from the VPS. However, the VPS is not a "central server" for Syncthing — when devices can connect directly, they still transfer directly.
This article uses Syncthing v2.1.3 and the official Docker image to explain Docker Compose, device pairing, folder modes, version retention, conflict files, .stignore, port 22000, WireGuard private networking, backup and restore, and common failures. The most important conclusion first: sync is not backup — deletions, overwrites and ransomware modifications can all propagate to other nodes.
Cases where Syncthing is a good fit:
- Syncing files between Windows, macOS, Linux, Android and NAS;
- Wanting a VPS as an always-on relay and replica node;
- Not wanting to hand files to a third-party cloud drive;
- Needing fast direct connections on the LAN, with automatic fallback to direct or Relay over the internet;
- Wanting per-folder control over send, receive, version retention and ignore rules;
- Being able to maintain the VPS, permissions, firewall and independent backups yourself.
Cases where it is not suitable:
- Needing multiple people to edit the same Office document online;
- Needing browser share links, online previews and complex permissions;
- Treating the sync directory as your only backup, with no snapshots or offline backups at all;
- Needing strict enterprise auditing, file approval and data loss prevention;
- Having a large number of small files changing frequently without assessing disk, database and scan overhead.
If you need cloud-drive-style web access and sharing, see the OpenList on a VPS tutorial. If you mainly manage contracts, invoices and scans, see the Paperless-ngx OCR document archiving tutorial.
| Tool | Sync method | Main advantages | Points to note |
|---|---|---|---|
| Syncthing | Continuous bidirectional sync across devices | Auto-discovery, encrypted transfer, cross-platform | Deletions and overwrites propagate |
| rsync | Command-line one-way copy | Simple, scriptable, suited to servers | Does not manage real-time state across devices |
| rclone | Cloud storage copy and sync | Supports many object stores and cloud drives | Real-time bidirectional sync is not its core capability |
| Nextcloud | Centralized cloud drive and collaboration | Web UI, sharing, users and app ecosystem | Heavier service, depends on database and web |
| OpenList | Multi-storage aggregation and WebDAV | Unified mounting and browsing of cloud drives | Not a peer-to-peer sync system |
Syncthing is best for "these devices are all mine and I want the files to stay consistent automatically". It has no central account system; each device trusts another via Device ID, and file transfers use TLS encryption.
A typical architecture looks like this:
手机 ───────────────┐
│
笔记本 ── 直连/Relay ├── VPS Syncthing 常在线节点
│
家中 NAS ───────────┘
The VPS provides three main benefits:
- When other devices are not online at the same time, the VPS holds the latest copy;
- When the home network has no public entry point, the VPS is easier for devices to connect to;
- You can keep version directories and extra backups on the VPS.
However, if your phone and laptop are on the same LAN, Syncthing will usually try a direct LAN connection and does not need to route through the VPS. Do not mistake it for a traditional cloud drive where all traffic must pass through the VPS.
This article is written against the stable version verified in August 2026:
Syncthing v2.1.3
Docker image: syncthing/syncthing:2.1.3
Common ports:
| Port | Purpose | Needs public exposure |
|---|---|---|
| 8384/TCP | Web GUI | Not exposed by default; listen only on localhost or VPN |
| 22000/TCP | Direct file sync | Open when public direct connections are needed |
| 22000/UDP | QUIC file sync | Open when QUIC direct connections are needed |
| 21027/UDP | LAN discovery | Usually not needed on a public VPS |
Syncthing can also use public Relays. Even if 22000 is not open to the public, devices may still connect through a Relay, but speed and latency are usually worse than a direct connection.
Syncthing itself is lightweight; resources are mainly consumed by file scanning, hashing, database indexing and version retention:
| Scenario | Recommended configuration | Notes |
|---|---|---|
| A small number of documents and configs | 1 core, 1GB, 30GB SSD | Suitable for up to tens of thousands of files |
| Photos and family files | 2 cores, 2GB, 80GB+ SSD | Leave room for version directories and indexes |
| Many devices, many small files | 2-4 cores, 4GB+ | Focus on disk I/O and inodes |
Disk capacity must at least cover:
当前同步数据
+ 文件版本目录
+ 临时下载文件
+ Syncthing 索引数据库
+ 独立备份预留
If the source directory is 100GB and you enable long-term version retention, an 80GB VPS will definitely not be enough. Version history should have a retention period and a maximum count; it cannot grow without limit.
Confirm Docker and Compose:
docker version
docker compose version
If Docker is not installed, see the Docker deployment practical guide first.
Create the config, sync data and version directories:
sudo mkdir -p /opt/syncthing/config
sudo mkdir -p /opt/syncthing/data
sudo mkdir -p /opt/syncthing/versions
sudo chown -R 1000:1000 /opt/syncthing
sudo chmod 750 /opt/syncthing
cd /opt/syncthing
The official container uses UID 1000 and GID 1000 by default. Check the permissions of the target directories on the host first, so the container does not start but fail to write sync files.
Create /opt/syncthing/compose.yaml:
services:
syncthing:
image: docker.io/syncthing/syncthing:2.1.3
container_name: syncthing
hostname: vps-syncthing
network_mode: host
restart: unless-stopped
environment:
PUID: "1000"
PGID: "1000"
UMASK: "0022"
STGUIADDRESS: ""
volumes:
- ./config:/var/syncthing/config
- ./data:/var/syncthing/data
- ./versions:/var/syncthing/versions
healthcheck:
test:
- CMD-SHELL
- curl -fkLsS -m 2 127.0.0.1:8384/rest/noauth/health | grep -q OK
interval: 1m
timeout: 10s
retries: 3
The official Docker documentation recommends host network, because the default bridge network makes Syncthing see only the container address, which affects LAN discovery and direct-connection decisions. With host network, Syncthing controls its own listen addresses and ports, so firewall configuration must be more careful.
Set STGUIADDRESS to empty so Syncthing uses the GUI address from the config file. The initial configuration usually listens on 127.0.0.1:8384, keeping the admin interface off the public internet.
Check the configuration:
cd /opt/syncthing
docker compose config --quiet
Start it:
docker compose pull
docker compose up -d
docker compose ps
docker compose logs --tail=150 syncthing
Check GUI health status:
curl -fsS http://127.0.0.1:8384/rest/noauth/health
When healthy you will see OK. If the connection is refused, check the container logs and listen address:
sudo ss -lntup | grep -E ':(8384|22000)\b'
docker compose logs --tail=250 syncthing
Create a tunnel on your own computer:
ssh -L 8384:127.0.0.1:8384 your_user@your_vps_ip
Open in your browser:
http://127.0.0.1:8384
After logging in for the first time, do three things immediately:
- Set a GUI username and a separate strong password;
- Confirm the GUI Listen Address is still 127.0.0.1:8384;
- Give devices clear names, such as vps-sync, home-nas, work-laptop.
The Device ID identifies the device certificate, not the GUI password. Only share it with devices that need to pair; the GUI API Key and admin password must be kept secret.
If you want devices to connect directly to the VPS, open 22000 TCP and UDP:
sudo ufw allow 22000/tcp
sudo ufw allow 22000/udp
sudo ufw status numbered
Usually do not open 21027/UDP on a public VPS. It is mainly used for LAN broadcast discovery; syncing across the internet relies on global discovery, static addresses or Relay.
Confirm 8384 is not publicly exposed:
sudo ufw status
sudo ss -lntp | grep ':8384'
As long as the GUI listens on 127.0.0.1, even if the firewall mistakenly allows 8384, the outside world usually cannot connect. But a secure configuration should restrict both the listen address and the firewall; do not rely on only one layer.
If all devices have already joined WireGuard, you can skip opening public 22000 and only allow the VPN subnet:
sudo ufw allow from 10.66.66.0/24 to any port 22000 proto tcp
sudo ufw allow from 10.66.66.0/24 to any port 22000 proto udp
In the client's remote device address, enter:
tcp://10.66.66.1:22000
quic://10.66.66.1:22000
You can then disable global discovery and Relay to reduce external metadata exposure. For WireGuard deployment, see the WireGuard VPN on a VPS tutorial.
Note: after disabling discovery and Relay, a wrong address configuration leaves no automatic fallback path. Confirm VPN routing and 22000 reachability before disabling the automatic connection mechanisms.
Find this device's Device ID in the VPS GUI, then on another device choose Add Remote Device. Enter the VPS Device ID, set the device name and address.
Recommended pairing process:
- On device A, add device B;
- On device B, accept the pending device;
- Both sides verify the displayed Device ID;
- Do not share important directories yet; share only a test folder;
- After confirming connection type, upload/download and deletion behavior, migrate your data.
A device showing Connected does not mean the folder is already shared. Device trust and folder sharing are two separate layers of configuration; you must select the allowed devices in the folder settings.
Add a folder on the VPS:
Folder Label: Personal Sync
Folder ID: personal-sync
Folder Path: /var/syncthing/data/personal
Folder Type: Send & Receive
The corresponding host directory is:
/opt/syncthing/data/personal
Create it and fix permissions:
sudo mkdir -p /opt/syncthing/data/personal
sudo chown -R 1000:1000 /opt/syncthing/data/personal
The Folder ID must be identical across shared devices, but the Folder Path can differ on each device. For example, Windows uses D:\Sync\Personal and the VPS uses /var/syncthing/data/personal.
All devices can modify files, and changes sync to each other. Suitable for personal documents, photos and project files, but most prone to propagating accidental deletions and conflicts.
This device is treated as the primary source. Local content is sent to other devices, and remote modifications do not normally overwrite the local authoritative copy. Suitable for making a NAS or work computer the primary data source.
This device mainly receives data from other nodes. When unsynced local modifications appear, it prompts Revert Local Changes. Suitable for a VPS acting as a receive-only replica, but it is still not an independent backup.
An untrusted device stores only encrypted file blocks and cannot read file contents directly. Suitable for a rented VPS acting only as an encrypted storage node.
Receive Encrypted requires the folder password to be stored correctly on trusted devices. If the password is lost, the encrypted data on the VPS cannot be recovered directly. Before deployment, use test files to confirm the encryption, recovery and migration process.
Syncthing's versioning mainly protects against "deletions and overwrites synced in from other devices". Common types:
- Trash Can: moves old files to the versions directory;
- Simple File Versioning: adds timestamps to old versions and keeps a fixed number;
- Staggered File Versioning: keeps recent versions densely and older versions progressively sparser;
- External File Versioning: calls a custom script to handle versions.
For home and personal scenarios, start with Staggered File Versioning and set the versions directory to:
/var/syncthing/versions/personal
Corresponding host path:
/opt/syncthing/versions/personal
Important limitation: versioning usually handles changes coming from remote devices. If you overwrite a file directly on the same device locally, a Syncthing version is not necessarily created. Truly important data still needs snapshots, restic or object storage backups.
Create .stignore in the root of the sync folder to ignore caches, build artifacts and temporary files:
(?d).DS_Store
Thumbs.db
~*
*.tmp
node_modules
.git
.cache
Verify rules in a test directory first. Ignoring database files, application configs or hidden directories may leave you missing critical data during recovery.
.stignore is a device-local rule; do not assume it will automatically propagate to all devices as you expect. When using multiple devices, check ignore rules and scan results on each one.
When two offline devices modify the same file at the same time, reconnecting may generate a file like:
report.sync-conflict-20260808-103000-DEVICE.txt
Handling steps:
- Pause the relevant folder;
- Compare the original file and the conflict file;
- Merge manually or keep the correct version;
- Delete the unneeded conflict copy;
- Resume syncing and watch whether conflicts reappear.
Syncthing does not understand the internal structure of Word, Excel or databases and cannot automatically merge complex files. Continuously written files such as SQLite, virtual machine disks and mail databases are not suitable for direct real-time sync; use the application's own export or consistent backup instead.
Windows, macOS and Linux can use the corresponding platform clients. Common Android options include community-maintained clients; iOS is limited by background execution and the file system, and third-party clients behave differently from the desktop version.
On mobile, note that:
- System power-saving policies may pause background sync;
- Syncing over cellular networks consumes a lot of data;
- Photo directory permissions may be restricted by the system;
- The client may not keep scanning after you exit it;
- Limit the folder scope before the first sync.
Do not start by syncing your entire phone storage or user home directory. Start with one test folder and verify charging, Wi-Fi, background and conflict behavior.
Syncthing faithfully propagates changes, including bad ones:
- Accidental file deletion;
- Ransomware bulk encryption;
- Applications writing corrupted data;
- Buggy scripts renaming or emptying directories;
- Users overwriting the wrong version onto all devices.
Prepare at least one independent backup:
Syncthing 实时同步
+ VPS/存储快照
+ restic 或 rclone 异地备份
+ 定期恢复演练
See the VPS backup and restore drill tutorial.
Stop the container before backing up the Syncthing config:
cd /opt/syncthing
docker compose stop
sudo tar -czf syncthing-config-$(date +%F).tar.gz config compose.yaml
docker compose start
chmod 600 syncthing-config-*.tar.gz
Sync data should be handled with an independent backup tool; do not just pack it onto the same VPS disk.
Before upgrading, record the current image and back up the config:
cd /opt/syncthing
docker inspect syncthing --format '{{.Config.Image}}'
sudo tar -czf syncthing-before-upgrade-$(date +%F).tar.gz config compose.yaml
After changing the image tag, run:
docker compose pull
docker compose up -d
docker compose ps
docker compose logs --tail=200 syncthing
After upgrading, check:
- GUI login and device list;
- Direct, QUIC or Relay connection type;
- Folder scan and sync status;
- Whether the versions directory is still writable;
- Ignore rules and folder passwords;
- Whether the health check passes.
Syncthing 2.x may upgrade the internal database. Do not casually roll back to an older major version without a config backup; read the Release Notes first and test on a replica node if necessary.
Check the listen address and container status:
docker compose ps
docker compose logs --tail=200 syncthing
sudo ss -lntp | grep ':8384'
curl -v http://127.0.0.1:8384
If the GUI only listens on 127.0.0.1, you must use an SSH tunnel or access it on the VPS itself. Do not change it to 0.0.0.0 for convenience without setting authentication and a firewall.
First check the remote address and port 22000:
sudo ss -lntup | grep ':22000'
sudo ufw status
nc -vz your_vps_ip 22000
Then look at Connections and logs in the GUI. If direct connection fails but Relay works, it is usually a firewall, NAT or address configuration issue.
Relay means the devices have not established a direct connection. Check:
- Whether VPS 22000 TCP/UDP is allowed;
- Whether the client network restricts UDP;
- Whether global discovery is enabled;
- Whether the static address is entered incorrectly;
- Whether WireGuard routing covers the VPS private address.
Confirm TCP direct connection first, then troubleshoot QUIC; do not change all connection options at once.
Check the container UID/GID and host directories:
docker compose exec syncthing id
ls -ld /opt/syncthing/data /opt/syncthing/versions
sudo chown -R 1000:1000 /opt/syncthing/data /opt/syncthing/versions
If syncing an external disk or network mount, also check mount options, ACLs and whether the file system supports permissions and renaming.
Syncthing uses a .stfolder marker in the folder root. Sync pauses when the directory is replaced, the mount fails or the marker is accidentally deleted.
First confirm the real data disk is mounted, then restore the marker. Do not click resume sync directly on an empty directory, or the "empty directory" may be propagated to other devices as a deletion result.
Many small files, frequent changes and multiple versions increase database and scan overhead. You can:
- Exclude node_modules, caches and build directories;
- Reduce unnecessary full-scan frequency;
- Move logs, databases and virtual machine disks out of the sync directory;
- Check disk I/O, inodes and free space;
- Split into multiple folders by purpose.
Syncthing v2.1 supports disabling block indexing for specific folders to reduce database size and overhead, but it lowers incremental transfer efficiency. Enable it only after understanding the trade-off and completing tests.
- GUI 8384 listens only on localhost or the WireGuard private network;
- GUI has a username and strong password set, and the API Key is not public;
- Only the 22000 TCP/UDP that is actually needed is open to the public;
- A public VPS usually does not open 21027/UDP;
- Global discovery and Relay can be disabled when not needed;
- Device IDs are exchanged only with devices that need to pair;
- Versioning is enabled for important folders, but the versions directory is not treated as the only backup;
- Databases, virtual machine disks and continuously written application files are not synced;
- Conflict files, failed items and disk space are checked regularly;
- Config, data and backups use different recovery paths;
- Pin the version and back up the config before upgrading;
- Receive Encrypted folder passwords are stored on trusted devices and in a password manager.
When a direct connection is possible, files transfer directly between devices. When direct connection fails, a Relay may be used, but file transfers are still end-to-end encrypted. The global discovery service mainly helps devices find each other.
As long as the other devices can connect to each other, syncing can continue. The VPS is just an always-on node, not a central controller that must exist.
Yes. Deletions in a Send & Receive folder usually propagate to other devices. Versioning and independent backups are needed to reduce the risk of accidental deletion.
You can use Receive Only. It reduces the risk of local mistakes on the VPS propagating, but ransomware or accidental deletions on the source device can still sync to the VPS, so versioning and snapshots are still needed.
For personal use, start with a 1-core 1GB VPS, Syncthing v2.1.3, one test folder and SSH tunnel management. First confirm that device pairing, file creation, modification, deletion, conflicts and version recovery all behave as expected, then gradually expand the sync scope.
A stable Syncthing architecture is not "all devices bidirectionally sync the entire disk", but rather splitting folders by purpose, choosing the right mode for each node, restricting the GUI and sync ports, and keeping a genuinely recoverable backup outside the sync system.