Skip to content
Cloudj

VPS how-to

A VPS backup strategy that survives your own mistakes

Build a VPS backup strategy that works: the 3-2-1 rule, restic or borg to off-server storage, database dumps, custom images and real restore tests.

Updated · 6 min read

A VPS backup strategy has one job: when something goes wrong, you get your data and your service back within a time you can live with. Most outages on a single server are not hardware failures. They are a wrong rm -rf, a migration that corrupts a table, a compromised plugin, or a deleted server. A good plan assumes you will make one of those mistakes and makes sure the copy you need is somewhere the mistake cannot reach.

This article is about strategy first and commands second. It does not rely on any provider-side backup feature: everything below runs from your own server to storage you control.

Start with two questions

Before choosing tools, write down two numbers for each server.

  • How much data can you lose? If the answer is "one day", a nightly backup is enough. If it is "a few minutes", you need database replication or frequent dumps, not just file backups.
  • How long can you be down? If you can be down for an afternoon, rebuilding from a clean image and restoring data is fine. If you need minutes, you need a standby server, which is a different project.

These answers decide how often you back up and how much you invest in fast rebuilds. Everything else is detail.

The 3-2-1 rule, applied to one VPS

The classic rule is three copies of your data, on two different kinds of storage, with one copy off-site. For a single cloud server it translates like this:

CopyWhere it livesWhat it protects against
1. Live dataThe server's own diskNothing, it is the thing you protect
2. Off-server backupA separate machine or storage service, in another locationDeleted server, ransomware, provider-side incidents
3. Second backupA different provider, or a machine at home or the officeA problem with copy 2 or the account that holds it

The key word is "off-server". A backup on the same disk, or a cron job that copies files into /backup on the same VPS, disappears together with the server. Keep at least one copy that the server can write to but cannot delete, for example an append-only repository or a storage account with separate credentials.

What to back up (and what not to)

Back up the things you cannot recreate from a script:

  • Application data: uploads, /var/www, user files.
  • Databases, as consistent dumps (see below), not as raw data files copied while the database is running.
  • Configuration: /etc, your Nginx sites, systemd units, cron jobs, .env files stored safely.
  • Anything in Docker volumes that holds state.

Skip what you can rebuild: the operating system, installed packages, node_modules, caches and logs you do not need to keep. A smaller backup is faster to run and much faster to restore.

Database dumps come first

Copying /var/lib/postgresql or /var/lib/mysql while the server runs can give you a backup that will not start. Dump the database to a file, then back up the file.

sudo mkdir -p /var/backups/db

# PostgreSQL: compressed custom format, restore with pg_restore
sudo -u postgres pg_dump -Fc appdb > /var/backups/db/appdb.dump

# MySQL or MariaDB: consistent snapshot of InnoDB tables
mysqldump --single-transaction --routines appdb | gzip > /var/backups/db/appdb.sql.gz

On newer MariaDB the same tool is called mariadb-dump. Run the dump a few minutes before the file backup so the backup always contains a fresh dump. For more on running PostgreSQL itself, see setting up PostgreSQL on a VPS.

Off-server backups with restic or borg

Both tools make encrypted, deduplicated backups: after the first run, each backup only stores what changed, and you can keep many restore points cheaply. Pick one.

restic

restic talks to many backends, including SFTP and S3-compatible object storage. The example uses SFTP to a separate backup host.

sudo apt install -y restic
export RESTIC_REPOSITORY=sftp:[email protected]:/srv/restic/web1
export RESTIC_PASSWORD_FILE=/root/.restic-password

restic init
restic backup /etc /var/www /var/backups/db --exclude-caches
restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune
restic check

restic calls each restore point a "snapshot"; that is restic's own term and has nothing to do with server snapshots. The restic documentation covers every backend.

borg

borg works over SSH to any machine with borg installed and is known for efficient deduplication.

sudo apt install -y borgbackup
export BORG_REPO=ssh://[email protected]/./borg/web1
export BORG_PASSCOMMAND="cat /root/.borg-passphrase"

borg init --encryption=repokey-blake2
borg create --stats ::'{hostname}-{now}' /etc /var/www /var/backups/db
borg prune --keep-daily 7 --keep-weekly 4 --keep-monthly 6
borg compact

With either tool, store the repository password somewhere other than the server. If the server is gone and the password lived only on it, the backup is unreadable.

Schedule it

A root crontab entry is enough for most servers:

15 3 * * * /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1

Put the dump, backup and prune commands in backup.sh, and have it send a message on failure. A backup job that fails silently for a month is worse than none, because you believe you are covered.

Custom images: a rebuild aid, not a backup

Cloudj lets you save your own custom images of a server and deploy new servers from them. That is useful for recovery speed: an image of a fully configured server (packages, Nginx, users, agents) lets you rebuild the base system in one step, then restore the latest data from restic or borg on top.

Treat an image as a template, not as your data backup. It captures one moment, you make it by hand, and it is not the off-server, versioned copy that the 3-2-1 rule asks for. Refresh the image after major configuration changes and keep data in your file backups.

Test restores on a schedule

A backup you have never restored is a hope. Once a month, or after any change to the backup script:

  1. Create a temporary server. Hourly billing suits this well; see hourly vs monthly VPS billing.
  2. Install restic or borg, point it at the repository and restore the latest backup to a scratch directory: restic restore latest --target /tmp/restore-test.
  3. Load the database dump and start the app.
  4. Note how long it took. That is your real recovery time.
  5. Delete the temporary server so it stops costing money.

Also restore one single file from a few weeks ago. Most real restores are "I deleted this config yesterday", not total loss.

A starting VPS backup strategy for one small server

  • Nightly database dump at 03:00, file backup with restic or borg at 03:15.
  • Keep 7 daily, 4 weekly and 6 monthly restore points.
  • Repository on a machine in a different location, with credentials the web server cannot use to delete history.
  • A second copy synced weekly to another provider or an office machine.
  • A custom image refreshed after big changes.
  • A monthly restore test with the time written down.

If you are also thinking about where the backup host should live, the VPS locations guide helps you pick a second region, and choosing a VPS location by latency explains why distance matters less for nightly backups than for user traffic. Pair this plan with the secure new VPS checklist so an attacker cannot reach your backups through the server.

FAQ

Does Cloudj back up my server automatically?

Do not assume any provider keeps a copy of your data for you. Run your own off-server backups as described here; Cloudj gives you custom images to speed up rebuilds.

Is RAID or a second disk on the same server a backup?

No. It protects against one disk failing, not against deletion, corruption or losing the server. Backups need to be separate and versioned.

restic or borg, which should I choose?

restic if you want object storage or many backend types. borg if you back up over SSH to a machine you control. Both are mature; the restore test matters more than the choice.

How long should I keep backups?

Long enough to notice a problem. Silent corruption or a compromise can go unnoticed for weeks, so keep monthly restore points for at least a few months.

Build the plan before you need it

Set up backups the same day you deploy, while the server is still small and simple. You can create a server and a separate backup host in the Cloudj console, and the pricing page shows live prices for each location and size.

Deploy a server or order proxies

Pick a location in the console, see the live price, and pay from your balance.