DEV Community

Cover image for Self-Hosting Without Backups Is Just Data Loss With Extra Steps
FlatlinerAtheist | CLI-NERDS
FlatlinerAtheist | CLI-NERDS

Posted on Originally published at clinerds.com

Self-Hosting Without Backups Is Just Data Loss With Extra Steps

There is a moment every self-hoster eventually has. You are admiring your setup — the dashboards, the tidy Docker Compose file, the photo timeline — and a small voice asks: "and if this machine dies tomorrow, what do I actually get back?"

For a lot of us, the honest answer is: nothing. We built a single point of failure and decorated it nicely. A self-hosted server without backups is not a Google replacement; it is data loss with extra steps.

This is the backup strategy I landed on after overcomplicating it twice and under-doing it once. It is boring, cheap, and it survives the failure scenarios that actually happen.

The rule: 3-2-1, translated to human

You have probably seen 3-2-1: three copies of your data, on two different kinds of storage, with one copy off-site. Here is what that looks like for a normal self-hosted setup:

  1. The live data on your server
  2. A local backup — a second drive, a NAS, another machine in the house
  3. An off-site backup — a friend's server, a relative's old laptop, or object storage

Why both a local and an off-site copy? Because they fail differently. The local copy is fast to restore when you fat-finger a migration. The off-site copy is what saves you when the house power supply fries the server and the backup disk sitting next to it. One protects against mistakes, the other against disasters.

What to back up (it is less than you think)

Do not back up the whole operating system. Back up the things you cannot re-download:

  • Application data — your Nextcloud data directory, Immich's library, photo folders
  • Databases — via proper dumps, not by copying the data directory of a running database (see the PostgreSQL backup guide for why and how)
  • Configuration — your docker-compose.yml, .env files, nginx configs, fstab, anything you would hate to reconstruct from memory

Everything else — the OS, Docker images, packages — is replaceable with an installer and an afternoon. A good test: if losing it would only cost you time, skip it. If losing it would cost you memories or a weekend of archaeology, back it up.

The tools: rsync first, restic or borg when you are ready

For the local copy, rsync is enough. Simple, transparent, and you can read the backup with no special software:

rsync -avh --delete /mnt/usb/nextcloud-data/ /mnt/backup/nextcloud-data/
Enter fullscreen mode Exit fullscreen mode

--delete mirrors deletions, which is what you want for a true copy — but be careful with it, because it also means a deleted file disappears from the backup on the next run. That is why the next tool exists.

For the off-site copy, use restic or borg. They give you deduplication, encryption, and snapshots over time, so you can go back to "last Tuesday" instead of just "latest". A restic example:

restic -r sftp:backupbox:/srv/restic-repo init
restic -r sftp:backupbox:/srv/restic-repo backup /mnt/usb/nextcloud-data /etc/nginx
Enter fullscreen mode Exit fullscreen mode

Snapshots are the feature that saves you from the sneakiest failure of all: silent corruption or a ransomware-style mess that gets faithfully synced to every mirror before you notice. A mirror is not a backup if it just mirrors the damage. Versioned snapshots are.

Schedule it, then make failure loud

A backup you run manually is a backup you will stop running. Cron is fine:

# local mirror, nightly at 03:00
0 3 * * * rsync -avh /mnt/usb/nextcloud-data/ /mnt/backup/nextcloud-data/ >> /var/log/backup.log 2>&1
# off-site, nightly at 04:00
0 4 * * * restic -r sftp:backupbox:/srv/restic-repo backup /mnt/usb/nextcloud-data >> /var/log/backup.log 2>&1
Enter fullscreen mode Exit fullscreen mode

The important part is the "loud" bit. Set up some way to notice silence — even a weekly calendar reminder to eyeball the log, or a healthchecks.io-style dead-man's switch that alerts you if the job does not check in. Backups do not usually fail dramatically; they fail quietly and get discovered at the worst time.

The restore drill — the part that makes it real

Once a month, restore something. Not the whole server, just proof that the pipeline works:

restic -r sftp:backupbox:/srv/restic-repo restore latest --target /tmp/restore-test
ls /tmp/restore-test
Enter fullscreen mode Exit fullscreen mode

Open a few restored files. Then, occasionally, do the bigger test: point a scratch install of the app at the restored data and log in. I know this sounds like homework. It is also the only difference between "I have backups" and "I can recover", and those are very different statements at 2 AM.

If you do only three things this weekend

  1. Plug in a second drive and set up a nightly rsync of your irreplaceable data
  2. Set up restic to any machine outside your house, even an old laptop at a relative's place
  3. Restore one folder and actually open the files

Your self-hosted stack only counts as "yours" if you can get it back after the worst day. Until then, you are just renting from your own hardware.

Top comments (0)