Most people discover the weaknesses of their server backup setup at the worst possible moment: the backup exists, but it is missing the uploads folder, or the database copy is corrupt, or the only copy was on the server that just failed. Good backups are less about which tool you use and more about a handful of habits. This guide covers those habits for Linux servers, with examples you can adapt.
Decide what you are protecting against
Different threats need different protections, and a backup plan should cover all of them:
- Hardware or disk failure: any copy on separate storage helps.
- Human error: an accidental
rmor a bad deployment. You need point-in-time copies from before the mistake. - Software bugs and corruption: may go unnoticed for days, so you need older versions too, not just last night's.
- Ransomware or a compromised server: attackers delete reachable backups. You need copies the server itself cannot alter.
- Losing the whole site or provider account: you need copies somewhere else entirely.
What to include in a server backup
Back up everything you would need to rebuild the service, not just the obvious data:
| Item | Typical location | Notes |
|---|---|---|
| Website and application files | /var/www, /home, /srv | Include user uploads, which are often outside version control |
| Databases | MySQL/MariaDB, PostgreSQL, MongoDB | Use dumps or database-aware tools, not raw file copies |
| Configuration | /etc | Web server, PHP, firewall, cron, SSL configs |
| Scheduled jobs | /var/spool/cron, /etc/cron.d | Easily forgotten until they stop running |
/var/mail, /home/*/Maildir | If the server hosts mailboxes | |
| Certificates and keys | /etc/letsencrypt, custom paths | Encrypt and protect carefully |
| Container volumes | /var/lib/docker/volumes | Stop or dump the service first for consistency |
You can usually skip /proc, /sys, /dev, /tmp, caches and the operating system files that a reinstall provides, provided you also record the list of installed packages (dpkg --get-selections or rpm -qa).
Back up databases properly
Copying the files of a running database can produce a backup that will not restore, because data is mid-write. Use the database's own tools:
# MySQL / MariaDB (InnoDB tables): consistent dump without locking
mysqldump --single-transaction --routines --triggers --all-databases \
| gzip > /backup/mysql-$(date +%F).sql.gz
# PostgreSQL: custom format allows selective restore
sudo -u postgres pg_dump -Fc appdb > /backup/appdb-$(date +%F).dump
For large or busy databases, physical backup tools such as Percona XtraBackup or Mariabackup (MySQL family) and pgBackRest or Barman (PostgreSQL) are faster and support point-in-time recovery using transaction logs. On managed cloud databases, enable automated backups and point-in-time recovery, and still export periodic copies outside the provider.
Snapshots vs file-level backups
Snapshots of a virtual machine disk or LVM volume are fast to take and restore a whole server in one step. But they usually live with the same provider or storage system, may not be application-consistent unless databases are flushed or paused, and restoring a single file can be awkward.
File-level backups with tools such as BorgBackup, restic or rsync are portable, can be stored anywhere, and make individual file restores easy. The best setups use both: snapshots for quick whole-server recovery, file-level backups for flexibility and offsite safety.
Full, incremental and deduplicated backups
- Full: everything, every time. Simple, but slow and storage-hungry.
- Incremental: only changes since the last backup. Fast, but traditional restores may need a chain of increments.
- Deduplicating: tools like Borg and restic split data into chunks and store each unique chunk once. Every backup behaves like a full snapshot for restore purposes while using little extra space.
A BorgBackup example sending encrypted, deduplicated backups to a remote host over SSH:
borg init --encryption=repokey-blake2 backup@vault.example.com:/srv/borg/web01
borg create --stats --compression zstd \
backup@vault.example.com:/srv/borg/web01::{hostname}-{now} \
/etc /var/www /backup
borg prune --keep-daily 7 --keep-weekly 4 --keep-monthly 6 \
backup@vault.example.com:/srv/borg/web01
Export and safely store the repository key (borg key export); without it, encrypted backups cannot be restored.
Keep at least one copy out of reach
Follow the 3-2-1 principle: three copies, on two types of storage, one offsite. Then go further:
- Pull, do not push, where possible. A backup server that connects in to fetch data means the production server holds no credentials to delete backups.
- Use append-only or immutable storage. Borg supports append-only repositories; object storage offers object lock.
- Use separate credentials and accounts for backup storage.
Set retention deliberately
A typical policy keeps 7 daily, 4 weekly and 6 to 12 monthly copies. Adjust for your recovery needs and any legal requirements to keep, or to delete, certain data. Remember that personal data in backups is still subject to data protection rules.
Automate, monitor and test
- Automate with cron or systemd timers; manual backups get skipped.
- Monitor for success, not just failure. Alert if no successful backup is recorded within the expected window, because a job that never starts sends no error.
- Check sizes. A backup that suddenly shrinks is a warning sign.
- Test restores monthly for single files and databases, and periodically for a full server onto fresh hardware.
- Document where backups live, how to access them and how to restore, stored somewhere that survives the server's loss.
Backup design, monitoring and restore testing are included in our server management and database management services.
Key takeaways
- Back up files, databases, configuration, cron jobs, certificates and volumes, not just the web root.
- Use database-aware dumps or tools, never raw copies of live database files.
- Combine snapshots with encrypted, deduplicated file-level backups stored offsite.
- Keep one copy the server cannot delete, monitor for success, and test restores regularly.