Ask a business whether they have backups and the answer is almost always “yes”. Ask when they last tested a restore, and it gets quiet. Hardware failures, ransomware, hacked plugins, a wrong rm -rf or a failed update can happen to any server. Backups are only valuable if you can restore from them.
This guide shows a simple, reliable backup setup for Linux servers (web shops, WordPress, Magento, n8n and other applications) using the 3-2-1 rule and restic.
The 3-2-1 backup rule
- 3 copies of your data (the original plus two backups)
- On 2 different types of storage
- With 1 copy off-site
Many people add a modern extension: 3-2-1-1-0:
- 1 copy that is offline or immutable (cannot be changed or deleted by an attacker)
- 0 errors in restore tests
What to back up
For a typical web server:
- Databases (MySQL/MariaDB, PostgreSQL), as consistent dumps
- Application files: uploads, media,
wp-content,pub/media, configuration files - Configuration: web server config,
.envfiles, cron jobs, SSL setup - Secrets: encryption keys and credentials, stored separately in a password manager
Do not back up what you can rebuild: caches, generated/ code, node_modules, vendor/ (if you deploy from Git and Composer).
Why restic?
Restic is a free, open-source backup tool that is:
- Encrypted by default
- Deduplicated: only changed data is stored, so daily backups are small
- Able to back up to many targets: local disk, SFTP, S3-compatible object storage, Backblaze B2 and more
- Simple to use from the command line
Borg (with borgmatic) is a good alternative with similar features.
Step 1: Install restic
On Debian/Ubuntu:
sudo apt install restic
Step 2: Create a repository
Example with S3-compatible object storage:
export AWS_ACCESS_KEY_ID=your-key
export AWS_SECRET_ACCESS_KEY=your-secret
export RESTIC_REPOSITORY=s3:https://s3.example-provider.com/my-backups
export RESTIC_PASSWORD_FILE=/root/.restic-password
restic init
Store the restic password in a password manager as well. Without it, your backups cannot be decrypted.
Step 3: Dump the databases
MySQL / MariaDB (consistent dump for InnoDB without locking the shop):
mysqldump --single-transaction --quick --routines --triggers shop_db | gzip > /var/backups/db/shop_db.sql.gz
PostgreSQL:
pg_dump -U app app_db | gzip > /var/backups/db/app_db.sql.gz
Step 4: Run the backup
restic backup /var/backups/db /var/www/shop/pub/media /etc/nginx /home/deploy/.env \
--exclude /var/www/shop/var/cache
Step 5: Set retention
Keep a sensible history and remove old snapshots:
restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune
This keeps one backup per day for a week, per week for a month and per month for half a year.
Step 6: Check repository integrity
restic check
Run it regularly, for example weekly.
Step 7: Automate with a script and cron
Create /usr/local/bin/backup.sh:
#!/bin/bash
set -euo pipefail
source /root/.restic-env
mysqldump --single-transaction --quick shop_db | gzip > /var/backups/db/shop_db.sql.gz
restic backup /var/backups/db /var/www/shop/pub/media /etc/nginx
restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune
Schedule it at night:
30 2 * * * /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1
Add monitoring. A backup that fails silently for three months is a common disaster. Use a “dead man’s switch” monitoring service or a small workflow that alerts you when the backup did not report success.
Step 8: Test restores
List snapshots:
restic snapshots
Restore to a test location:
restic restore latest --target /tmp/restore-test
At least every few months, restore to a separate test server and check that the application actually runs. That is the only real proof that your backups work.
Protecting against ransomware
If an attacker gains root access on your server, they can also delete backups the server can write to. Protect yourself with:
- Append-only or immutable storage (object lock / versioning on S3-compatible storage)
- Pull backups from a separate backup server, so the web server has no delete rights
- Separate credentials that are not stored on the production server where possible
Snapshots vs backups
VPS and cloud snapshots are useful for fast rollbacks before updates, but they are often stored with the same provider and sometimes in the same location. Use them in addition to off-site backups, not instead of them.
Backup checklist
| Item | Done? |
|---|---|
| Databases dumped consistently | |
| Media and config files included | |
| Off-site encrypted copy | |
| Immutable or offline copy | |
| Retention policy set | |
| Monitoring and alerts | |
| Restore tested in the last 3 months | |
| Passwords and keys in password manager |
Frequently asked questions
How often should I back up my web shop?
At least daily for most shops. Busy shops with many orders per hour often back up the database more frequently or use replication plus point-in-time recovery.
Is my hosting provider’s backup enough?
It is a useful extra layer, but you usually cannot control retention, location or restore speed. Keep your own off-site backup too.
Restic or Borg?
Both are excellent. Restic supports many cloud storage backends directly; Borg is very efficient and commonly used with SSH-based storage. Choose the one that fits your storage target.
Want backups you can trust?
I set up and maintain servers, backups and restore procedures for web shops and business applications. See my servers, virtualisation and backups service or request help.