Good backups are boring: they run every night, take little space, are encrypted, and you never think about them until you need them. BorgBackup with the borgmatic wrapper gets you there with a single config file. (Prefer restic and object storage? See backing up a VPS to cloud storage.)
What you’ll set up
- Source: your VPS (files + database dumps).
- Target: a second server reachable over SSH — ideally in another location — with Borg installed.
- borgmatic: runs backups, database dumps, pruning and consistency checks on a schedule.
1. Prepare the backup server
On the backup server:
apt install -y borgbackup
adduser --disabled-password --gecos "" borg
mkdir -p /srv/borg && chown borg: /srv/borg
2. SSH key from the VPS
On the VPS (as root):
apt install -y borgbackup borgmatic
ssh-keygen -t ed25519 -f /root/.ssh/borg -N ""
cat /root/.ssh/borg.pub
On the backup server, add the key to /home/borg/.ssh/authorized_keys, restricted to Borg and one repository path:
command="borg serve --restrict-to-path /srv/borg/web1",restrict ssh-ed25519 AAAA… root@web1
The VPS can now only run Borg in its own repository — it can’t get a shell on the backup server.
3. Configure borgmatic
borgmatic config generate # creates /etc/borgmatic/config.yaml
Edit it to something like:
source_directories:
- /etc
- /var/www
- /home
- /root
repositories:
- path: ssh://[email protected]/srv/borg/web1
label: offsite
exclude_patterns:
- '*/cache/*'
- '*.log'
encryption_passcommand: cat /root/.borg-passphrase
ssh_command: ssh -i /root/.ssh/borg
compression: zstd,6
keep_daily: 7
keep_weekly: 4
keep_monthly: 6
checks:
- name: repository
frequency: 2 weeks
- name: archives
frequency: 1 month
mariadb_databases:
- name: all
# postgresql_databases:
# - name: all
(Recent borgmatic versions use this flat format; older versions group options into sections — follow the generated file.)
Create the passphrase and store a copy in your password manager:
openssl rand -base64 32 > /root/.borg-passphrase && chmod 600 /root/.borg-passphrase
4. Initialize and run
borgmatic rcreate --encryption repokey-blake2 # 'init' on older versions
borgmatic --verbosity 1 --stats
Export the repository key as well (with repokey, it’s stored in the repo, protected by the passphrase):
borg key export ssh://[email protected]/srv/borg/web1 /root/borg-key.txt
Keep that file somewhere safe off the server.
5. Schedule it
The borgmatic package ships a systemd timer on Debian/Ubuntu:
systemctl enable --now borgmatic.timer
systemctl list-timers borgmatic.timer
Or use cron: 0 3 * * * borgmatic --verbosity -1 --syslog-verbosity 1.
6. Monitor
borgmatic can ping a monitoring service at start, finish and failure:
healthchecks:
ping_url: https://hc-ping.com/YOUR-UUID
You’ll get an alert if a backup fails or doesn’t run at all.
7. Restore
borgmatic rlist # list archives ('list' on older versions)
borgmatic extract --archive latest --path var/www/example.com --destination /tmp/restore
borgmatic restore --archive latest # restore database dumps
Or mount and browse:
mkdir /mnt/borg && borgmatic mount --archive latest --mount-point /mnt/borg
Practice a restore every month. A backup you haven’t restored isn’t proven.
Protect against ransomware
If an attacker gains root on the VPS, they could try to delete backups. Mitigations:
--restrict-to-pathandrestricton the SSH key (done above).- Add
--append-onlyto theborg servecommand so the VPS can add archives but not delete them; run pruning from the backup server instead.
Choosing a backup target
A small second VPS in a different location makes an affordable, fast backup server. For large data sets, a Storage VPS gives you hundreds of gigabytes of SSD. Related: Debian backup and disaster recovery and VPS maintenance.