Skip to content
DevOps devops security 5 min read

Backups & Disaster Recovery

A backup is a second copy of your data that you can restore from if the original is lost. Disasters happen: a disk dies, a bad command wipes a database, ransomware encrypts your files, or a whole datacentre catches fire. Backups are the difference between “we lost an hour” and “we lost the company.” This page shows you a practical, tested backup strategy on Ubuntu, because a backup you have never restored is just a hope, not a plan.

Why backups are a security topic

Backups protect the availability of your data, which is one of the three pillars of security (alongside confidentiality and integrity). Ransomware (malware that encrypts your files and demands payment) is now one of the most common attacks, and the only reliable cure is restoring from a clean, offline backup. So backups are not just an ops chore; they are a core security control.

The 3-2-1 rule

The 3-2-1 rule is the industry-standard baseline for backups. It is simple to remember and hard to beat:

  • 3 copies of your data (the live one plus two backups).
  • 2 different types of media or storage (for example, a local disk and cloud object storage).
  • 1 copy offsite (in a different physical location from your server).

The offsite copy is the part most people skip, and it is the most important. If your backup lives on the same server as the data, a single disk failure, fire, or a compromised root account destroys both at once.

Gotcha: A backup that an attacker can delete is not a real backup. If your server’s credentials can erase the cloud copy, ransomware can too. Use immutable or versioned storage (for example, S3 Object Lock or restic with append-only repos) so backups cannot be silently deleted.

RPO and RTO: how much can you lose, how fast must you recover

Two terms drive every backup decision. Define them with your team before you build anything.

TermFull nameQuestion it answersExample target
RPORecovery Point ObjectiveHow much data can I afford to lose?”At most 1 hour of changes”
RTORecovery Time ObjectiveHow long can I be down while I recover?”Back online within 2 hours”

A 15-minute RPO means you must back up at least every 15 minutes. A 2-hour RTO means your restore process must be fast and rehearsed. Tighter targets cost more money and effort, so pick numbers that match the real business need, not the most paranoid one.

What to back up

Do not back up only “the database” and call it done. A working recovery needs everything required to rebuild the service.

WhatWhere on UbuntuNotes
Databasespg_dump, mysqldump, or replicasSee your DB backup page
App data / uploadse.g. /var/www, /srvUser-generated files
Server config/etc (nginx, systemd, ufw, postgresql)Lets you rebuild fast
Secrets & certs/etc/letsencrypt, env files, vault keysEncrypt these copies
Cron jobs & timers/etc/cron.d, systemd timersEasy to forget

Security tip: Backups of secrets and TLS private keys are still secrets. Always encrypt backups at rest, and restrict who can read the backup storage.

Automating backups with restic

restic is a modern, free backup tool that does encryption, deduplication (storing repeated data only once), and snapshots out of the box. It can write directly to cloud storage, which gives you the offsite copy automatically.

Install it:

sudo apt update
sudo apt install -y restic
restic version

Output:

restic 0.16.4 compiled with go1.22 on linux/amd64

Initialise an encrypted repository (here in a local backup disk; point the path at cloud storage for offsite):

export RESTIC_REPOSITORY=/mnt/backup/restic-repo
export RESTIC_PASSWORD='use-a-long-random-passphrase'
restic init

Output:

created restic repository 8f2c1a4e9b at /mnt/backup/restic-repo
Please note that knowledge of your password is required to access the repository.

Run a backup of your important directories:

restic backup /etc /var/www /srv

Output:

Files:        1843 new,    0 changed,    0 unmodified
Added to the repository: 214.512 MiB (61.203 MiB stored)
snapshot a1b2c3d4 saved

Schedule it with a systemd timer

A systemd timer is the modern Ubuntu way to run a job on a schedule (more reliable than cron for this). Create the service:

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

[Service]
Type=oneshot
Environment=RESTIC_REPOSITORY=/mnt/backup/restic-repo
EnvironmentFile=/etc/restic/password.env
ExecStart=/usr/bin/restic backup /etc /var/www /srv
ExecStartPost=/usr/bin/restic forget --keep-daily 7 --keep-weekly 4 --prune
# /etc/systemd/system/restic-backup.timer
[Unit]
Description=Run restic backup daily

[Timer]
OnCalendar=*-*-* 02:30:00
Persistent=true

[Install]
WantedBy=timers.target

Store the password file with tight permissions, then enable the timer:

sudo mkdir -p /etc/restic
echo "RESTIC_PASSWORD=use-a-long-random-passphrase" | sudo tee /etc/restic/password.env
sudo chmod 600 /etc/restic/password.env
sudo systemctl daemon-reload
sudo systemctl enable --now restic-backup.timer
systemctl list-timers restic-backup.timer

Output:

NEXT                        LEFT       UNIT                 ACTIVATES
Tue 2026-06-16 02:30:00 UTC 9h left    restic-backup.timer  restic-backup.service

The forget --prune step enforces a retention policy (how long you keep old backups), so storage does not grow forever.

Testing your restores

This is the rule everyone breaks and the one that matters most: an untested backup is not a backup. Schedule a real restore drill at least monthly. Restore into a throwaway directory or a spare server and confirm the data is actually usable.

mkdir -p /tmp/restore-test
restic restore latest --target /tmp/restore-test
ls /tmp/restore-test/etc/nginx/sites-available

Output:

default  myapp.conf

Check repository integrity regularly so silent corruption is caught early:

restic check

Output:

no errors were found

For databases, a restore test means loading the dump into a scratch database and running a query, not just confirming the file exists. Tie this into your database backup procedures.

Best Practices

  • Follow 3-2-1: three copies, two media types, one offsite. The offsite copy is non-negotiable.
  • Encrypt every backup at rest, especially anything containing secrets or TLS private keys.
  • Use immutable or versioned backup storage so ransomware and bad scripts cannot delete your history.
  • Automate backups with a systemd timer and a retention policy so they happen even when you forget.
  • Define explicit RPO and RTO targets and verify your tooling actually meets them.
  • Test restores on a schedule (monthly at minimum) and run restic check to catch corruption.
  • Document the full recovery steps so anyone on the team can run them under pressure.
Last updated June 15, 2026
Was this helpful?