Kennisbank › Linux › Automatische backups instellen op Linux
linux gemiddeld 17 September 2026

Automatische backups instellen op Linux

Een backupscript dat je één keer met de hand draait is geen backup, het is een goed voornemen.Dit artikel zet een automatische backup op met `rsync` en een

Een backupscript dat je één keer met de hand draait is geen backup, het is een goed voornemen.

Dit artikel zet een automatische backup op met `rsync` en een systemd timer op Debian 12 of Ubuntu 24.04. Je leert waarom je voor timers kiest in plaats van cron, hoe je de service en timer aan elkaar knoopt, en hoe je controleert of het echt loopt.

Vereisten

  • Een Linux-systeem met systemd als init. Debian 12, Ubuntu 22.04 of 24.04, Rocky 9 — allemaal prima. Check met `systemctl --version`.
  • `rsync` versie 3.2 of hoger. Installeer met `sudo apt install rsync` of `sudo dnf install rsync`.
  • Een doelopslag: een tweede schijf, een NAS via SSH, of een externe mount. Lokaal backuppen naar dezelfde schijf beschermt je tegen domme fouten, niet tegen een kapotte schijf.
  • Root of sudo. De timer draait in dit voorbeeld systeembreed, niet per user.

Waarom timers en niet cron

Cron werkt. Het is klein, het staat overal, en voor "draai dit script elke nacht om 02:30" is het prima. Maar cron heeft twee eigenschappen die je bij backups pijn doen.

Ten eerste: als de machine uit stond op het geplande moment, wordt de taak overgeslagen. Geen inhaalslag, geen melding. Je komt maandagochtend terug van een weekend en de zondagbackup is nooit gedraaid.

Ten tweede: logging. Cron gooit output in syslog of in de mail van root, en die mail leest niemand. Systemd timers loggen naar de journal, met `journalctl` kun je per unit precies zien wat er draaide, wanneer, en met welke exit code.

De prijs: je schrijft twee bestanden in plaats van één regel. Een `.service` en een `.timer`. Dat is meer typwerk voor meer grip.

Stappen

1. Zet het backupscript neer

Maak `/usr/local/bin/backup.sh`. Dit script synchroniseert een bronmap naar een doel, en logt wat het doet.

```bash #!/bin/bash set -euo pipefail

SRC="/home/" DEST="/mnt/backup/home/" LOG="/var/log/backup.log"

echo "=== Backup gestart: $(date -Is) ===" >> "$LOG"

rsync -aAXH --delete \ --exclude='.cache/' \ --exclude='.local/share/Trash/' \ "$SRC" "$DEST" >> "$LOG" 2>&1

echo "=== Backup klaar: $(date -Is) ===" >> "$LOG" ```

De flags doen het echte werk. `-a` bewaart permissies, tijden en symlinks. `-A` en `-X` houden ACLs en extended attributes vast — laat je die weg, dan verlies je SELinux-labels en sommige rechten. `-H` bewaart hardlinks. `--delete` gooit bestanden op de bestemming weg die in de bron verdwenen zijn, zodat je een spiegel krijgt en geen archief dat langzaam vol loopt.

Die `--delete` is ook het gevaarlijke deel. Staat `SRC` per ongeluk leeg of verkeerd, dan wist `rsync` je backup. Test het script altijd eerst met `--dry-run` erbij voordat je het automatiseert.

Maak het uitvoerbaar:

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

2. Test het script handmatig

Draai het één keer met de hand en kijk of de bestemming klopt.

```bash sudo /usr/local/bin/backup.sh ```

Loop daarna door `/mnt/backup/home/` en vergelijk een paar bestanden. Een backup die je nooit hebt teruggezet, is een hypothese.

3. Schrijf de service unit

Maak `/etc/systemd/system/backup.service`. De service beschrijft wát er draait, niet wanneer.

```ini [Unit] Description=Rsync backup van /home naar /mnt/backup After=local-fs.target

[Service] Type=oneshot ExecStart=/usr/local/bin/backup.sh Nice=10 IOSchedulingClass=idle ```

`Type=oneshot` vertelt systemd dat dit een taak is die afrondt, geen daemon die blijft draaien. `Nice=10` en `IOSchedulingClass=idle` duwen de backup naar de achtergrond qua CPU en I/O, zodat een draaiende backup je server niet platlegt tijdens piekuren.

4. Schrijf de timer unit

Maak `/etc/systemd/system/backup.timer`. De timer beschrijft wanneer de service start.

```ini [Unit] Description=Dagelijkse backup om 02:30

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

[Install] WantedBy=timers.target ```

`OnCalendar=-- 02:30:00` betekent elke dag om half drie. De notatie is `jaar-maand-dag uur:minuut:seconde`, en `` staat voor "maakt niet uit". Je kunt ook `OnCalendar=daily` schrijven, maar dan moet je de documentatie erbij pakken om te weten hoe laat dat precies is. Expliciet is beter.

`Persistent=true` is de reden dat je hier bent. Als de machine uit stond om 02:30, draait systemd de taak alsnog zodra hij weer opstart. Cron doet dat niet.

`RandomizedDelaySec=10m` spreidt de starttijd met een willekeurige vertraging tot tien minuten. Op één server maakt dat niets uit. Op honderd servers die allemaal om 02:30 naar dezelfde NAS schrijven, scheelt het je een netwerkstorm.

5. Herlaad systemd en activeer de timer

Systemd leest nieuwe unit-bestanden pas na een reload.

```bash sudo systemctl daemon-reload sudo systemctl enable --now backup.timer ```

`enable` zorgt dat de timer na een reboot automatisch start. `--now` start hem meteen, zodat je niet op 02:30 hoeft te wachten.

6. Test de service los van de timer

Je wilt niet een dag wachten om te zien of het werkt. Start de service direct.

```bash sudo systemctl start backup.service ```

Dit draait het script nu, buiten het schema om. De timer blijft gewoon staan voor de volgende geplande run.

Verificatie

Check of de timer actief is en wanneer hij voor het eerst draait:

```bash systemctl list-timers backup.timer ```

Je krijgt een regel met `NEXT` (het volgende tijdstip), `LAST` (de vorige run) en `UNIT` (de naam). Staat `NEXT` op een tijdstip in de toekomst, dan is de timer ingeplant.

Bekijk daarna wat de service heeft gedaan:

```bash systemctl status backup.service journalctl -u backup.service -n 50 --no-pager ```

`status` toont de laatste exit code. `journalctl` toont de output van je script, inclusief de rsync-regels. Zie je daar `exit code 0`, dan is de backup geslaagd. Zie je een fout, dan staat de oorzaak in dezelfde output.

Veelgestelde problemen

De timer draait, maar de service faalt met "Permission denied". De service draait als root, maar het script schrijft naar `/var/log/backup.log` en `/mnt/backup/`. Controleer of die paden bestaan en of root er mag schrijven. Een mount die pas later in de boot verschijnt is een klassieker — voeg `RequiresMountsFor=/mnt/backup` toe aan de `[Unit]` sectie van de service.

`systemctl list-timers` toont niets. De timer is niet geactiveerd. Draai `sudo systemctl enable --now backup.timer` opnieuw. Check ook met `systemctl status backup.timer` of er een fout in het unit-bestand zit — een typefout in `OnCalendar` laat systemd de timer weigeren.

De backup duurt uren en loopt over in de volgende dag. `rsync` vergelijkt alles opnieuw als de metadata niet klopt. Zorg dat `-a` er staat, anders verandert de mtime bij elke run en denkt rsync dat alles nieuw is. Voor grote datasets is `rsnapshot` een betere keuze dan een zelfgeschreven script: het bouwt hardlink-snapshots, dus je houdt meerdere versies zonder de schijf vol te schrijven.

Een backup die je nooit hebt getest is geen backup. Zet een keer een bestand terug.

← Terug naar kennisbank
← Terug naar kennisbank