Applies to: Debian 13 and Ubuntu 24.04 and 26.04 with MariaDB 11.8 or MySQL 8.4; restic 0.16.4 (Ubuntu 24.04), 0.18 (Debian 13, Ubuntu 26.04) and 0.19.1 (EPEL for AlmaLinux 9)
To back up a Linux server, dump the databases to files, then copy those dumps and your important folders (/etc, the web roots, /home, /root) to another machine, on a schedule, keeping several older versions. A backup that stays on the same server doesn’t protect you from a disk failure, a hacked account or a mistaken rm. This guide builds that with standard tools and restic, then shows how to restore.
1. Decide what to back up
- Configuration:
/etc(web server, PHP, SSH, firewall, certificates in/etc/letsencrypt). - Websites and app data:
/var/www,/srv,/home, and/root(scripts,.my.cnf). - Databases: as dumps, not the raw files in
/var/lib/mysql, which can be inconsistent while the server runs. - Scheduled jobs and mail:
/var/spool/cronand mail folders if the server hosts mail. - Skip caches,
/tmp,/proc,/sysand anything you can reinstall. A list of installed packages is enough:apt-mark showmanual > /root/packages.txt.
2. Dump the databases
Put the database login in /root/.my.cnf (chmod 600) so it isn’t on the command line, then:
mariadb-dump --single-transaction --routines --events --databases shopdb | gzip > /var/backups/db/shopdb.sql.gz
On MySQL the commands are mysqldump and mysql (we checked mysqldump Ver 8.4.11). --single-transaction gives a consistent copy of InnoDB tables without locking the site. For PostgreSQL use pg_dump per database. Test the restore once: in our test, zcat shopdb.sql.gz | mariadb recreated the dropped database with its rows.
3. A quick local archive with tar
tar -czf /backup/files-$(date +%F).tar.gz --exclude=/var/www/site/cache /etc /var/www
tar prints Removing leading `/' from member names, which is normal. To restore one file into a separate folder:
tar -xzf /backup/files-2026-09-30.tar.gz -C /tmp/restore var/www/site/p1.html
This is fine before a risky change, but it is still on the same server. For regular backups, send copies elsewhere.
4. Off-site, encrypted and versioned with restic
restic stores encrypted, deduplicated snapshots, so a daily run only uploads what changed. It can write to another server over SFTP, to S3-compatible storage and more. Install it with sudo apt install restic (Debian, Ubuntu) or from EPEL on AlmaLinux.
On the backup server, create a user (here backup) and add the web server root’s SSH public key to its ~/.ssh/authorized_keys (see set up SSH keys): restic needs to log in without a password prompt for automatic backups. Then, on the web server, create the repository:
echo 'a-long-random-password' > /root/.restic-pass chmod 600 /root/.restic-pass restic -r sftp:backup@backup.example.com:/srv/restic/web01 --password-file /root/.restic-pass init
restic warns that losing the password means the data is lost for good. Keep a copy of it somewhere other than the server.
A backup script, /usr/local/sbin/server-backup.sh (chmod 700), that we ran successfully with restic 0.16.4 and MariaDB 11.8:
#!/bin/bash set -euo pipefail umask 077 export RESTIC_REPOSITORY="sftp:backup@backup.example.com:/srv/restic/web01" export RESTIC_PASSWORD_FILE="/root/.restic-pass" # 1. Dump each database to a file (login details in /root/.my.cnf) mkdir -p /var/backups/db for db in $(mariadb -N -e "SHOW DATABASES" | grep -Ev "^(information_schema|performance_schema|sys)$"); do mariadb-dump --single-transaction --routines --events --databases "$db" | gzip > "/var/backups/db/$db.sql.gz" done # 2. Send files and dumps to the repository restic backup /etc /var/www /home /root /var/backups/db --exclude "/var/www/*/cache" # 3. Keep 7 daily, 4 weekly and 6 monthly snapshots, delete the rest restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune
umask 077 matters: without it the dumps were created readable by every user. Run it every night at 02:30 with a file /etc/cron.d/server-backup:
30 2 * * * root /usr/local/sbin/server-backup.sh >> /var/log/server-backup.log 2>&1
5. Check and restore
restic snapshots # list backups restic ls latest /var/www/site # browse a snapshot restic restore latest --target /tmp/restore --include /var/www/site/index.html restic check # verify the repository
Restore into a separate folder, compare, then copy back what you need. A backup you have never restored is only a hope: try a full restore of one site and one database to a test server now and then. A wrong password gives Fatal: wrong password or no key found.
Other options
- A plain
rsynccopy to another server: back up your files with rsync and a VPS. Simple, but without restic’s versions and encryption. - An image of the whole disk: back up a Linux OS with dd.
- An agent-based service: Acronis Cyber Protect Cloud for Linux servers.
- Encrypting a single archive before you upload it: GnuPG symmetric encryption.
If you would rather have an engineer set up and test backups for you, see server management or hire an expert.
Official documentation: restic and mariadb-dump.