Tutorial

How to Self-Host a Reliable Backup in 2026 (Step by Step)

Why this matters

Most self-hosted stacks die the same way: nobody tested the restore. You have snapshots, you have a cron job, you have faith — and then a disk dies and you realize the backup was silently failing for months.

This guide is the exact setup I run to back up a small server. It’s not fancy, and that’s the point.

What I tested on

  • OS: Debian 13 (trixie)
  • restic: 0.17.3
  • rclone: 1.68.0
  • Hardware: one local NVMe, one offsite S3-compatible bucket
  • Duration: running daily for 8 months at the time of writing

⚠️ Replace every path, bucket name and password below with your own values before running anything.

How I tested

I didn’t just run a backup. I picked a random Tuesday, deleted a file on purpose, and restored it. That’s the only test that counts — everything else is hope.

Step 1: Install restic

sudo apt update
sudo apt install -y restic rclone
restic version

You should see restic 0.17.3. If you get something older, grab the binary from the official releases.

Step 2: Initialize the repository

export RESTIC_REPOSITORY="/srv/backup/restic"
export RESTIC_PASSWORD="a-real-password-not-this-one"

restic init

Keep that password somewhere safe — lose it and your backups are unrecoverable. I store mine in a password manager and on a printed piece of paper in a drawer.

Step 3: Your first backup

restic backup \
  --exclude="/var/lib/docker/volumes/*/log" \
  --exclude="/tmp" \
  /srv/data \
  /etc \
  /var/lib/docker/volumes

The first run is slow because it hashes everything. Subsequent runs only upload changes — that’s the whole point of restic.

Step 4: Forget and prune (the part everyone skips)

A backup without pruning is just a disk-filler. Add this:

restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune

What this means in plain English: keep 7 daily snapshots, 4 weekly and 6 monthly. Old ones get removed and their data is reclaimed.

Step 5: Automate it

I use a systemd timer rather than cron — it logs better and handles missed runs.

# /etc/systemd/system/restic-backup.service
[Unit]
Description=Restic backup

[Service]
Type=oneshot
ExecStart=/usr/bin/restic backup --exclude="/tmp" /srv/data
Environment=RESTIC_REPOSITORY=/srv/backup/restic
Environment=RESTIC_PASSWORD_FILE=/etc/restic/password
# /etc/systemd/system/restic-backup.timer
[Timer]
OnCalendar=daily
Persistent=true

[Install]
WantedBy=timers.target
sudo systemctl daemon-reload
sudo systemctl enable --now restic-backup.timer

Step 6: Send it offsite

This is the step that turns a backup into a disaster recovery plan. I mirror the repository to an S3-compatible bucket with rclone:

rclone sync /srv/backup/restic remote:my-backup-bucket \
  --fast-list \
  --transfers 4

Run this after the restic backup succeeds, not before. And yes, encrypt the bucket too.

How to actually verify it works

Once a month, pick a file you don’t mind losing, delete it, and run:

restic restore latest --target /tmp/restore-test --include /srv/data/some-file.txt

If you can’t restore, the backup doesn’t exist. It’s that simple.

What I’d change if I started over

Three things, after running this for eight months.

I would test the restore in week one, not month three. The first time I ran a full restore it took two hours, because I had excluded a directory that turned out to hold the restic password file. The backup had worked perfectly; my ability to use it had not. Test with the worst case: a machine that is gone, not a directory you deleted on purpose.

I would store the repository password in three places. Password manager, printed paper, and a sealed copy at a second address. Two of those are useless if the house floods, which is the scenario a 3-2-1 setup is supposed to survive.

I would pick the offsite provider before buying disks. The disk size decides your local retention; the provider’s pricing and egress rules decide whether you can afford to restore. The B2 numbers I published are the kind of thing worth reading before, not after, you have 2 TB to upload.

What I would not change: restic with --prune on a monthly timer, one bucket, one password, and a calendar reminder to restore something once a quarter. Boring is the feature.

If the machine doing the backing up is a hypervisor, do the snapshot dance described in the Proxmox review before the backup runs — a consistent snapshot beats a fast one.

Pros and cons

Pros:

  • Deduplicates automatically, so incremental backups are tiny
  • Repository is encrypted on disk
  • restic check can verify integrity without a full restore

Cons:

  • Pruning is slow on large repositories
  • No built-in web UI — it’s a CLI tool
  • Offsite sync is a separate step you must remember

Best for / Skip if

Best for: self-hosted servers with a few hundred GB of data and someone who’s comfortable in a terminal.

Skip if: you want a pretty dashboard and one-click restore. Look at something with a UI instead, and accept that you’ll pay for it.

Alternatives

  • BorgBackup — similar idea, different internals; some people find it faster
  • Duplicati — has a web UI, easier for beginners
  • Plain rsync — fine for file copies, but no deduplication or encryption

Verdict

restic plus rclone is my default answer for self-hosted backups because it’s boring in the best way: it does one job, does it well, and stays out of your way. The only catch is that you must test restores — the tool won’t do that for you.

The setup above has saved me twice in eight months. Both times it was a stupid mistake, not a disk failure. That’s usually how it goes.

References

FAQ

How much space does restic need for the repository?

Roughly the size of your source data plus overhead. With 500 GB of data I see about 520 GB used, because deduplication only helps across snapshots.

Can I back up a running database?

Not safely with restic alone. Snapshot the volume first (LVM/ZFS/Btrfs), then back up the snapshot.

What happens if the backup process is interrupted?

Nothing bad. Restic is transactional — re-run the command and it picks up where it left off.

Should I encrypt the repository even if the server is mine?

Yes. Offsite buckets get compromised, and unencrypted backups are a data leak waiting to happen.

Henry Xiang

I keep self-hosted services alive for a living — backups, docs, monitoring, the boring parts that break at 3am. Everything here runs on my own hardware first.