How to Back Up a Linux Server (rsync, tar and a Nightly Script)

Back up your server tonight: rsync, tar, cron. Then test it.

Drives fail, rm -r happens in the wrong folder, and updates occasionally break things. A backup is the difference between an annoying hour and a lost year. You don't need fancy software: rsync to copy files, tar to bundle them, cron to do it every night, and a second drive or another machine to put them on.

Quick reference

TaskCommand
Mirror a folder to another driversync -a --delete /home/ /mnt/backup/home/
Dated archive of a foldertar -czf /mnt/backup/etc-$(date +%F).tar.gz /etc
Dump a MariaDB/MySQL databasemysqldump --all-databases > /mnt/backup/db-$(date +%F).sql
Restore an archivetar -xzf etc-2026-10-08.tar.gz -C /
Delete backups older than 30 daysfind /mnt/backup -name "*.tar.gz" -mtime +30 -delete

1. Decide what to back up

Not the whole disk — the operating system can be reinstalled in twenty minutes. Back up what you can't get back:

2. rsync to a second drive

Mount a second drive (tutorial 22) at /mnt/backup, then:

sudo rsync -a --delete /home/ /mnt/backup/home/
sudo rsync -a --delete /var/www/ /mnt/backup/www/

-a preserves everything; --delete removes files from the backup that you've deleted from the source, so it stays an exact mirror. Trailing slashes on both sides. The first run copies everything; later runs take seconds.

To back up to another machine instead, use the SSH form: rsync -a --delete /home/ john@192.168.1.60:/backup/home/.

3. tar for configs and databases

A mirror is overwritten each night. For things where you might want last Tuesday's version, make dated archives:

sudo tar -czf /mnt/backup/etc-$(date +%F).tar.gz /etc
sudo mysqldump --all-databases | gzip > /mnt/backup/db-$(date +%F).sql.gz

$(date +%F) puts today's date in the filename. Clear old ones out automatically:

find /mnt/backup -name "*.gz" -mtime +30 -delete

4. Put it in a script

sudo nano /usr/local/bin/backup.sh

#!/bin/bash
set -e
DEST=/mnt/backup
DATE=$(date +%F)

rsync -a --delete /home/ $DEST/home/
rsync -a --delete /var/www/ $DEST/www/
tar -czf $DEST/etc-$DATE.tar.gz /etc
mysqldump --all-databases | gzip > $DEST/db-$DATE.sql.gz
dpkg --get-selections > $DEST/packages-$DATE.txt
find $DEST -name "*-20*" -mtime +30 -delete

echo "backup ok $DATE"

sudo chmod +x /usr/local/bin/backup.sh
sudo /usr/local/bin/backup.sh

5. Run it every night

sudo crontab -e

0 2 * * * /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1

Check /var/log/backup.log occasionally for "backup ok".

6. Test a restore

A backup you've never restored from is a hope, not a backup. Once:

mkdir ~/restore-test
tar -xzf /mnt/backup/etc-2026-10-08.tar.gz -C ~/restore-test
ls ~/restore-test/etc

If the files are there, you're covered.

Off-site

A fire or theft takes the backup drive with the server. Once a month, copy the latest archives to a USB drive you keep elsewhere, or to cloud storage with rclone (rclone sync /mnt/backup remote:server-backup). For versioned, encrypted, deduplicated backups to anywhere, look at restic — it's one binary and worth learning once the basics are working.

Troubleshooting

mysqldump asks for a password in cron. Put credentials in /root/.my.cnf ([client] / user=root / password=..., chmod 600).

The backup drive wasn't mounted and rsync filled the system disk. Add mountpoint -q /mnt/backup || exit 1 as the first line of the script.

Permission denied on some files. Run the script as root (root's crontab), as above.

Wrapping up

Mirror the files with rsync, archive configs and databases with tar and mysqldump, run it from cron at 2 am, and restore one file to prove it works. Then get a copy off-site. Two hours of setup for a server you can't lose.

Call us