Backup Integration with Restic
Syncthing is a sync tool — if you delete a file, it disappears from all peers. For production data, sync must be combined with a backup solution. Restic is the natural complement: immutable snapshots, deduplication, and encryption.
Learning Focus
Build a layered data protection model: Syncthing for real-time availability across nodes, Restic for point-in-time recovery independent of sync propagation.
Tool Snapshot
| Tool | Role | Handles Deletion? | Encryption | Storage |
|---|---|---|---|---|
| Syncthing | Real-time replication | ❌ Propagates deletes | ✅ TLS in transit | Peer devices |
| Restic | Snapshot backup | ✅ Retains deleted files | ✅ AES-256 at rest | Any backend (S3, local, SFTP) |
Architecture Overview
flowchart LR
subgraph Node A — Primary
DATA["/var/www/html/docs"] --> SYNC[Syncthing]
DATA --> RESTIC[Restic backup]
end
subgraph Node B — Replica
SYNC --> DATA2["/var/www/html/docs (replica)"]
end
subgraph Backup Storage
RESTIC --> S3[S3 / Backblaze B2]
end
Rule of thumb: Syncthing keeps you available, Restic keeps you recoverable.
Installing Restic
install-restic.sh
# Debian/Ubuntu
sudo apt install restic -y
# Verify
restic version
Initializing a Backup Repository
init-restic-repo.sh
# Local repository (for testing)
restic init --repo /mnt/backup/syncthing-docs
# S3 (recommended for production)
export AWS_ACCESS_KEY_ID="your-key"
export AWS_SECRET_ACCESS_KEY="your-secret"
restic init --repo s3:s3.amazonaws.com/your-bucket/syncthing-backup
Set a strong, stored password:
# Store password securely
echo "yourStrongR3sticPassword" > /etc/restic-password
chmod 600 /etc/restic-password
Running a Backup After Sync Settles
backup-synced-dir.sh
#!/bin/bash
# Backup the Syncthing-managed directory with Restic
set -euo pipefail
REPO="/mnt/backup/syncthing-docs"
PASSWORD_FILE="/etc/restic-password"
SOURCE="/var/www/html/docs"
# Wait for any in-progress sync to settle (optional — Syncthing is safe to backup live)
sleep 5
restic backup \
--repo "$REPO" \
--password-file "$PASSWORD_FILE" \
--tag syncthing \
--exclude "*.syncthing" \
--exclude ".stversions" \
"$SOURCE"
echo "Backup complete: $(restic snapshots --repo $REPO --password-file $PASSWORD_FILE --last | tail -n1)"
# Apply retention policy
restic forget \
--repo "$REPO" \
--password-file "$PASSWORD_FILE" \
--keep-hourly 24 \
--keep-daily 7 \
--keep-weekly 4 \
--keep-monthly 12 \
--prune
note
Syncthing's .stversions directory contains internal version history files. Exclude it from Restic to avoid double-backing versioned data unless you specifically want it.
Automating with a systemd Timer
/etc/systemd/system/syncthing-backup.service
[Unit]
Description=Restic backup of Syncthing-managed directories
After=syncthing@syncthing.service
[Service]
Type=oneshot
User=syncthing
ExecStart=/usr/local/bin/backup-synced-dir.sh
StandardOutput=journal
StandardError=journal
/etc/systemd/system/syncthing-backup.timer
[Unit]
Description=Run Syncthing backup every 6 hours
[Timer]
OnBootSec=10m
OnUnitActiveSec=6h
Unit=syncthing-backup.service
[Install]
WantedBy=timers.target
sudo systemctl enable --now syncthing-backup.timer
# Verify next run
systemctl list-timers | grep backup
Restore Workflow
restore-from-restic.sh
REPO="/mnt/backup/syncthing-docs"
PASSWORD_FILE="/etc/restic-password"
# List snapshots
restic snapshots --repo "$REPO" --password-file "$PASSWORD_FILE"
# Restore a specific snapshot to a temporary directory
SNAPSHOT_ID="abc12345"
restic restore "$SNAPSHOT_ID" \
--repo "$REPO" \
--password-file "$PASSWORD_FILE" \
--target /tmp/restore-test
# Inspect the restored files
ls -la /tmp/restore-test/var/www/html/docs/
# Once verified, copy to the live Syncthing folder
rsync -av /tmp/restore-test/var/www/html/docs/ /var/www/html/docs/
Versioning Comparison
| Feature | Syncthing Versioning | Restic Snapshots |
|---|---|---|
| Max history | Configurable (staggered or simple) | Unlimited (retention policy) |
| Storage location | .stversions on the same device | Separate encrypted repository |
| Encryption at rest | ❌ Not encrypted | ✅ AES-256 |
| Recovery granularity | Per-file versions | Entire snapshot or per-file |
| Protects against accidental delete | ✅ Yes (while policy applies) | ✅ Yes (until prune) |
| Protects against ransomware | ⚠️ Partial | ✅ Yes (immutable repo) |
Common Mistakes
| Mistake | Risk | Fix |
|---|---|---|
| Relying only on Syncthing versioning for backup | Versions stored on same device — at risk of disk failure | Use Restic to off-device backup |
| Running backup while Syncthing is paused | Stale data backed up | Pause sync only during maintenance, not backup windows |
Skipping --prune in retention script | Repository grows unbounded | Always include --prune with forget |
| Not testing restores | Silent backup corruption goes unnoticed | Run restic check monthly and test restores quarterly |