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-path and restrict on the SSH key (done above).
  • Add --append-only to the borg serve command 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.

  • Backups
  • Borg
  • Linux