Syncthing File Synchronization Installation
Syncthing is an open-source, peer-to-peer file synchronization tool that keeps files in sync across multiple devices without relying on a central cloud service. Data is transferred directly between devices using TLS encryption, making Syncthing suitable for syncing sensitive files, self-hosted backups, and distributed content workflows on Linux.
Prerequisites
- Ubuntu/Debian or CentOS/Rocky Linux VPS or physical server
- Ports 22000/TCP, 22000/UDP, and 21027/UDP open between syncing devices
- Basic familiarity with the Linux terminal
Installing Syncthing
# Ubuntu/Debian - add official APT repository
curl -s https://syncthing.net/release-key.txt | sudo apt-key add -
echo "deb https://apt.syncthing.net/ syncthing stable" | \
sudo tee /etc/apt/sources.list.d/syncthing.list
sudo apt-get update
sudo apt-get install -y syncthing
# CentOS/Rocky - use YUM repository
sudo rpm --import https://syncthing.net/release-key.txt
sudo tee /etc/yum.repos.d/syncthing.repo << 'EOF'
[syncthing-stable]
name=Syncthing Stable Channel
baseurl=https://apt.syncthing.net/rpm/stable/
gpgcheck=1
gpgkey=https://syncthing.net/release-key.txt
EOF
sudo dnf install -y syncthing
# Verify installation
syncthing --version
Running Syncthing as a Service
# Enable and start Syncthing for a specific user
sudo systemctl enable syncthing@yourusername
sudo systemctl start syncthing@yourusername
sudo systemctl status syncthing@yourusername
# Check logs
journalctl -u syncthing@yourusername -f
# Syncthing web UI is available at http://localhost:8384 by default
# It's only bound to localhost for security
Expose Web UI via Nginx (Optional)
# /etc/nginx/sites-available/syncthing
server {
server_name sync.yourdomain.com;
location / {
proxy_pass http://localhost:8384;
proxy_set_header Host $host;
proxy_read_timeout 600s;
proxy_send_timeout 600s;
# Basic auth for added security
auth_basic "Syncthing";
auth_basic_user_file /etc/nginx/.htpasswd;
}
}
# Create password file
sudo htpasswd -c /etc/nginx/.htpasswd syncuser
sudo ln -s /etc/nginx/sites-available/syncthing /etc/nginx/sites-enabled/
sudo certbot --nginx -d sync.yourdomain.com
sudo systemctl reload nginx
# Configure Syncthing GUI to allow connections from Nginx
# Settings → GUI → GUI Listen Address: 127.0.0.1:8384
# Remove "Use HTTPS for GUI" since Nginx handles TLS
Device Pairing
Each Syncthing installation has a unique Device ID (fingerprint):
# Get your device ID
syncthing --device-id
# Or view in the web UI: Actions → Show ID
To pair two devices:
- Open the Syncthing web UI on Device A (
http://localhost:8384) - Go to Add Remote Device
- Enter Device B's Device ID
- Set a device name and optionally auto-accept folders
- Repeat on Device B, adding Device A's Device ID
- Both devices will show a pending connection request — accept it on each side
# Configure via CLI / config file
# Syncthing config is at: ~/.config/syncthing/config.xml (user)
# Or: /var/lib/syncthing/.config/syncthing/config.xml (service)
# Use the REST API to add a device
curl -X POST "http://localhost:8384/rest/config/devices" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"deviceID": "XXXXXXX-XXXXXXX-XXXXXXX-XXXXXXX-XXXXXXX-XXXXXXX-XXXXXXX-XXXXXXX",
"name": "backup-server",
"addresses": ["dynamic"],
"autoAcceptFolders": false
}'
Folder Sharing and Configuration
# Add a folder via REST API
curl -X POST "http://localhost:8384/rest/config/folders" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"id": "documents",
"label": "My Documents",
"path": "/home/user/Documents",
"type": "sendreceive",
"devices": [
{"deviceID": "REMOTE-DEVICE-ID"},
{"deviceID": "ANOTHER-DEVICE-ID"}
],
"rescanIntervalS": 3600,
"fsWatcherEnabled": true
}'
# Folder types:
# sendreceive - default, sync bidirectionally
# sendonly - send changes, don't receive (good for backups from client)
# receiveonly - receive changes, don't send (read-only mirror)
# receiveencrypted - encrypted-only copy (untrusted device)
Encrypted Folder Sharing
Send encrypted files to an untrusted device (no decryption key on that device):
# On the trusted device: add the untrusted device with an encryption password
# Web UI: Edit Folder → Sharing tab → Add device → set Encryption Password
# The untrusted device will sync encrypted blobs it cannot read
Versioning and Conflict Resolution
Configure file versioning per folder:
# Set versioning via API
curl -X PATCH "http://localhost:8384/rest/config/folders/documents" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"versioning": {
"type": "trashcan",
"params": {
"cleanoutDays": "30"
}
}
}'
# Versioning types:
# trashcan - keep deleted files for N days (like Recycle Bin)
# simple - keep last N versions
# staggered - time-based retention (hourly/daily/weekly/monthly)
# external - run a custom script on each version
Staggered Versioning Config
<!-- In config.xml folder section -->
<versioning type="staggered">
<param key="cleanInterval" val="3600"/>
<param key="maxAge" val="31536000"/> <!-- 1 year in seconds -->
</versioning>
Conflict resolution: Syncthing creates .sync-conflict-YYYYMMDD-HHMMSS-DEVICEID files when simultaneous edits occur. Review and merge them manually.
Ignore Patterns
Create .stignore in the root of each synced folder:
cat > ~/Documents/.stignore << 'EOF'
# Ignore system files
.DS_Store
Thumbs.db
desktop.ini
# Ignore temp and cache files
*.tmp
*.swp
*~
.cache
# Ignore build artifacts
node_modules
__pycache__
*.pyc
.git
dist/
build/
target/
# Ignore large media files (sync separately)
*.mkv
*.avi
*.iso
# Include specific subdirectory even if parent is ignored
!important-node-module/
EOF
# Common .stignore directives:
# // - comment
# * - matches any file
# ** - matches any path
# ? - matches single character
# !pattern - include (override previous exclusion)
# (?d) - delete on other devices when ignored locally
Relay Servers and Discovery
When devices can't communicate directly (NAT, firewall), Syncthing uses relay servers:
# View relay status in web UI: Actions → Advanced → relaysEnabled
# Or check via API
curl -s "http://localhost:8384/rest/system/connections" \
-H "X-API-Key: your-api-key" | python3 -m json.tool
# Run your own relay server
# Install syncthing-relaysrv
wget https://github.com/syncthing/relaysrv/releases/latest/download/relaysrv-linux-amd64.tar.gz
tar -xzf relaysrv-linux-amd64.tar.gz
./strelaysrv -listen=:22067 -pools=""
# Tell clients to use your relay
# Web UI: Settings → Connections → Sync Protocol Listen Address:
# Add: relay://your-server-ip:22067/?id=YOUR-DEVICE-ID
Docker Deployment
# docker-compose.yml
version: '3'
services:
syncthing:
image: syncthing/syncthing:latest
container_name: syncthing
environment:
- PUID=1000
- PGID=1000
volumes:
- /opt/syncthing/data:/var/syncthing
- /data/sync:/sync # Mount your sync directory here
ports:
- "8384:8384" # Web UI
- "22000:22000" # Sync protocol TCP
- "22000:22000/udp" # Sync protocol QUIC
- "21027:21027/udp" # Local discovery
restart: unless-stopped
healthcheck:
test: curl -fkLsS -m 2 127.0.0.1:8384/rest/noauth/health | grep -o '"OK"\|"ok"'
interval: 1m
timeout: 10s
retries: 3
docker compose up -d
docker compose logs syncthing -f
Troubleshooting
Devices not connecting:
# Check firewall allows Syncthing ports
sudo ufw allow 22000/tcp
sudo ufw allow 22000/udp
sudo ufw allow 21027/udp
# Test direct connectivity from client
nc -z -v remote-server-ip 22000
# Check connection status
curl -s "http://localhost:8384/rest/system/connections" \
-H "X-API-Key: your-api-key"
Sync stuck or not progressing:
# Check if folder is in sync error state
curl -s "http://localhost:8384/rest/db/status?folder=documents" \
-H "X-API-Key: your-api-key"
# Force rescan
curl -X POST "http://localhost:8384/rest/db/scan?folder=documents" \
-H "X-API-Key: your-api-key"
High CPU usage:
# Reduce rescan interval (default 3600s is fine, don't set to 0)
# Disable filesystem watcher if inotify limits are hit
echo "fs.inotify.max_user_watches = 204800" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
Conclusion
Syncthing's decentralized design means there's no single point of failure, no subscription cost, and no third-party holding your data. With encrypted folder sharing, flexible versioning, and custom relay servers, it can handle everything from simple two-device sync to complex multi-server distributed file infrastructure. Its Docker availability and REST API make it straightforward to integrate into existing Linux server environments.


