Private customers Business customers

Set up backups for your VPSAutomatic, encrypted and off the server

Automatic backups are not part of our VPS plans - with root access, you have every tool for them in your own hands. This guide shows a backup strategy that is in place within twenty minutes and then runs without you having to do anything.

rsync & BorgCron jobEncrypted30 minutes

Published on

How backups work with us

We do not create automatic backups of your VPS. That is a deliberate decision with two sides: you do not pay for a service that many people do not use anyway - and in return, the responsibility is yours.

What we do provide: the NVMe storage runs in RAID 1, so the data is mirrored on two drives. That protects against the failure of a single SSD - but nothing more. Against an accidental rm -rf, a broken database migration, ransomware or a failed update, RAID does not help at all. For that, you need a backup.

A good rule of thumb is still the 3-2-1 rule: three copies of the data, on two different media, one of them off-site. For a single VPS, that translates to: the live data, a local backup for quick access and an external backup for emergencies.

Rent a VPS from €2.95 / month

Prepaid without a contract, full root access.

View plans & prices

Step 1: Work out what actually needs backing up

A full image of the system is rarely necessary. You can reinstall the operating system in the web interface within a few minutes - only your own data is irreplaceable. The typical list:

  • Websites and applications: usually under /var/www/
  • Databases: do not copy the files, create a dump instead - more on that below
  • Configurations: /etc/nginx/, /etc/php/, systemd units under /etc/systemd/system/
  • Docker: the Compose files and the contents of the named volumes
  • Game servers: world folders and configuration files
  • Certificates: /etc/letsencrypt/ - they can be requested again, but backing them up saves time

Write this list down once. The most common backup problem is not the missing backup, but the incomplete one.

Step 2: Back up databases correctly

The classic mistake: copying the directory /var/lib/mysql while the database is running. The result may well be an inconsistent state that can no longer be restored. Create a dump instead:

sudo mkdir -p /var/backups/db
sudo mariadb-dump --single-transaction --all-databases | gzip > /var/backups/db/all-$(date +%F).sql.gz

The --single-transaction parameter is crucial: it ensures a consistent state without locking the database during the dump. For PostgreSQL, the counterpart is pg_dumpall.

So that no password appears in plain text in the script, create a protected credentials file:

sudo nano /root/.my.cnf
[client]
user=root
password=your-database-password
sudo chmod 600 /root/.my.cnf

For databases in a Docker container, the dump runs through the container:

docker compose exec -T db mariadb-dump --single-transaction -u root -pPASSWORD --all-databases | gzip > db-$(date +%F).sql.gz

Step 3: The simple option - rsync to an external target

If you have a second system - another VPS, a NAS at home, a computer with SSH access - rsync is the quickest way. It only transfers changes, which makes it suitable for larger amounts of data too.

First, generate and install an SSH key without a passphrase for the automated run:

sudo ssh-keygen -t ed25519 -f /root/.ssh/backup_key -N ""
sudo ssh-copy-id -i /root/.ssh/backup_key.pub backup@TARGET-SERVER

Then the backup script:

sudo nano /root/backup.sh
#!/bin/bash
set -euo pipefail

DATE=$(date +%F)
TARGET="backup@TARGET-SERVER:/backups/vserver/"
KEY="/root/.ssh/backup_key"

# 1. Database dump
mkdir -p /var/backups/db
mariadb-dump --single-transaction --all-databases | gzip > /var/backups/db/all-$DATE.sql.gz

# 2. Remove old dumps (older than 14 days)
find /var/backups/db -name "*.sql.gz" -mtime +14 -delete

# 3. Transfer
rsync -az --delete -e "ssh -i $KEY" \
  /var/www/ /etc/nginx/ /etc/letsencrypt/ /var/backups/db/ \
  "$TARGET"

echo "Backup $DATE completed"
sudo chmod 700 /root/backup.sh

The line set -euo pipefail matters more than it looks: it aborts the script on any error instead of silently carrying on and reporting an incomplete backup as a success.

Be careful with --delete: the parameter mirrors exactly and removes at the target whatever is missing at the source. If a directory is deleted by accident, the next run deletes the backup too. If you want to avoid that, use Borg.

Step 4: The recommended option - BorgBackup

BorgBackup solves exactly this problem: it creates versioned backup points, deduplicates across all runs and encrypts on the source system. Even if someone gains access to the backup target, your data is unreadable there.

sudo apt install borgbackup -y
sudo borg init --encryption=repokey-blake2 backup@TARGET-SERVER:/backups/borg-vserver

Store the passphrase and the repository key file outside the server. Without them, the backup is worthless - this is the point at which an otherwise good strategy fails in an emergency.

The matching script:

#!/bin/bash
set -euo pipefail

export BORG_PASSPHRASE='your-long-passphrase'
export BORG_RSH="ssh -i /root/.ssh/backup_key"
REPO="backup@TARGET-SERVER:/backups/borg-vserver"

mariadb-dump --single-transaction --all-databases | gzip > /var/backups/db/all.sql.gz

borg create --stats --compression zstd \
  "$REPO::{hostname}-{now:%Y-%m-%d_%H%M}" \
  /var/www /etc/nginx /etc/letsencrypt /var/backups/db

borg prune -v "$REPO" \
  --keep-daily=7 --keep-weekly=4 --keep-monthly=6

borg compact "$REPO"

The prune line keeps storage requirements in check: seven daily, four weekly and six monthly backup points. Thanks to deduplication, this takes up much less space than the number suggests.

Step 5: Automate with cron

A backup you have to start by hand will be forgotten at some point. Add it to cron:

sudo crontab -e
30 3 * * * /root/backup.sh >> /var/log/backup.log 2>&1

This runs the script every day at 3:30 am and writes the output including error messages to a log file. After the first run, check that everything went through:

tail -n 30 /var/log/backup.log

If you do not want to check the log regularly, hook up a notification service or have an email sent on errors. A backup that has been silently broken for weeks is more dangerous than none at all, because you rely on it.

Step 6: Test the restore

This is the step almost everyone skips - and the one that makes the difference in an emergency. A backup that has never been restored is, at best, an assumption.

With Borg, first look at what is actually there:

borg list "$REPO"
borg list "$REPO::ARCHIVENAME" | head

You restore a single file like this:

cd /tmp && borg extract "$REPO::ARCHIVENAME" var/www/mysite/index.php

And you import a database like this:

gunzip < all-2026-08-01.sql.gz | sudo mariadb

Set yourself a reminder to do this once a quarter. And think of the worst case: if your VPS has to be set up from scratch, you also need access to the backup target, the Borg passphrase and the private SSH key. If all of that lives only on the lost server, even the best backup will not help you.

Quick checklist

  • List made of which directories and databases are irreplaceable
  • Databases backed up as a dump, not as a file copy
  • Target is outside the VPS
  • Backup encrypted, passphrase stored separately
  • Cron job set up, first run checked in the log
  • Retention limited so the target does not fill up
  • Restore tested at least once

What goes into the list depends on what runs on the server: a web server with its databases, a Docker stack with volumes, a Nextcloud with its data directory or a Minecraft server with its worlds.

Frequently asked questions

No, automatic backups are not part of the plan. With root access, you have every tool for them in your own hands and decide on the scope, frequency and target of your backups. The NVMe storage runs in RAID 1, but that only protects against the failure of a single drive - not against operating errors, faulty software or ransomware.

No. RAID 1 mirrors write operations in real time to a second drive and thus protects against hardware failure. But if you delete a file by accident, it is gone from the mirror at the same moment. Only a time-delayed backup in another location helps against human error, faulty updates and ransomware.

To any system outside the server that can be reached via SSH: a second VPS, a NAS at home, a computer with a fixed address or a storage service with SSH or SFTP access. All that matters is that the target is not on the same server - a backup in the /backup directory of your VPS is just as lost as the original data in the event of a total loss.

With a dump, not by copying the database files. For MariaDB and MySQL, use "mariadb-dump --single-transaction", for PostgreSQL "pg_dumpall". The --single-transaction parameter ensures an internally consistent state without locking the database during the backup. A file copy taken during operation, on the other hand, often produces a state that can no longer be restored.

rsync is simpler and quicker to set up, but only mirrors the current state - a deleted file is also gone from the target after the next run. Borg creates versioned backup points, deduplicates across all runs and encrypts on the source system. For everything that really matters to you, Borg is the better choice.

With the prepaid model, the service expires on the due date if you do not renew it. So back up your data in good time beforehand. An automatic backup to an external target that is already set up takes this worry off your hands - the data is kept there regardless of the state of the server.

VPS with full root access

Root access means you choose your backup strategy yourself instead of relying on a predefined scheme. All plans with NVMe SSD in RAID 1, unmetered traffic and prepaid without a contract.

View VPS plans & prices