2026-06-06 8 min read

A Backup Strategy for Self-Hosters Who Keep Putting It Off

Everyone agrees backups matter. Then the server runs fine for six months, the backup script rots, and nobody notices until the disk fails.

A good backup strategy is boring, automated, and tested.

The minimum viable backup

For a small self-hosted server, back up four things:

Do not back up the whole operating system first. It is usually easier to rebuild the OS from notes and restore data than to recover a messy full-disk image.

Use two layers

Snapshots are useful but not sufficient.

Provider snapshots are fast and convenient. They help when an update breaks the server or you delete the wrong directory. But they live with the provider.

Off-site backups are your real disaster recovery. Store them with another provider, another account, or another physical location.

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

The classic backup rule scales down nicely to a single self-hosted server:

A concrete small-scale version: keep your live data on the VPS, take nightly provider snapshots for quick rollback, and push an encrypted Restic or Borg repository to a cheap storage VPS or object-storage bucket with a different provider. That single off-site copy is what saves you when the provider account itself is the problem.

Pick one backup tool

Restic and Borg are both excellent. Pick one and learn it properly.

You want:

Rclone is useful for moving data to many backends, but encryption and retention need more care.

Databases need deliberate handling

Do not rely on copying live database files unless you know the database supports it.

For small services, use dumps:

pg_dump app > app.sql
mysqldump app > app.sql
sqlite3 app.db ".backup app.db.backup"

Then back up the dumps with your backup tool.

Test restores

A backup you have never restored is a theory.

Once a month, restore to a temporary directory or test server:

This does not have to be a perfect disaster simulation. It just has to catch obvious failure.

Document the restore path

Write a short file:

1. Provision Debian VPS
2. Install Docker and Caddy
3. Restore /srv/app from restic
4. Restore database dump
5. Put secrets in /etc/app.env
6. Point DNS

That document is part of the backup.

Automate it, then get out of the way

A backup that depends on you remembering to run it is already broken. Wire the whole thing into a scheduler so it happens whether or not you are paying attention.

A minimal systemd timer (or a cron entry) that dumps the database and runs your backup tool is enough for most small servers:

# /etc/cron.daily/backup
#!/bin/sh
set -e
pg_dump app > /srv/dumps/app.sql
restic backup /srv/app /srv/dumps
restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune
restic check

The forget/prune step enforces retention so the repository does not grow forever, and restic check catches a corrupt repository before you need it. Send the script’s output somewhere you will actually see — an email, a healthcheck ping, or your monitoring of choice — so a silent failure becomes a loud one.

The goal is the same as the rest of this post: boring, automated, and tested. Set it up once, verify it restores, and let the machine do the remembering.

Tired of managing servers?

Love the idea but not the maintenance? OpsHelp can run your FOSS stack for you — managed hosting built on Hetzner, Cloudflare, and open source tooling. From £50/month.