31.03.2025 Backuplösung ist fertig

Und Grok hat auch eine Dokumentation erstellt:

Dokumentation für WPBackup.sh

Natürlich, hier ist eine ausführliche Dokumentation für dein WPBackup.sh-Skript. Sie beschreibt den Zweck, die Funktionsweise, die Voraussetzungen und die einzelnen Schritte des Skripts. Ich habe sie so gestaltet, dass du sie leicht verstehen und bei Bedarf anpassen kannst.

Dokumentation für WPBackup.sh

Zweck

Das Skript WPBackup.sh dient der automatisierten Sicherung eines WordPress-Verzeichnisses und der zugehörigen MySQL-Datenbank von einem Raspberry Pi (RaspWordpress, IP: 192.168.1.100) auf ein Synology NAS (ScharpNAS, IP: 192.168.0.11). Es wird auf einem Backup-Server (MultiTool, IP: 192.168.0.16) ausgeführt und unterstützt:

  • Vollständiges Backup am Montag.
  • Inkrementelle Backups an den restlichen Tagen der Woche.
  • Wake-on-LAN (WOL), um das NAS bei Bedarf zu starten.
  • Protokollierung aller Schritte in einer Log-Datei.

Das Skript ist für den Betrieb über cron optimiert und läuft als Benutzer BackupUser.

Voraussetzungen

Systemanforderungen

  • MultiTool (192.168.0.16):
    • Benutzer: BackupUser (UID: 1001, GID: 1001).
    • Installierte Pakete: rsync, ssh, wakeonlan, cifs-utils.
    • Optional: ssmtp für E-Mail-Benachrichtigungen.
  • RaspWordpress (192.168.1.100):
    • Benutzer: BackupUser mit SSH-Zugriff.
    • MySQL-Datenbank: dbs10597143 mit Zugriff für BackupUser.
    • WordPress-Verzeichnis: /var/www/html/ev-travel-blog/.
  • ScharpNAS (192.168.0.11):
    • Freigabe: //192.168.0.11/ScharpNAS/data/Daten_II/Backup/Raspberry/100_PI_WordPress.
    • MAC-Adresse: 00:11:32:F1:56:17 für WOL.

Konfiguration

  1. SSH-Schlüssel:
    • Passwortloser Zugriff von BackupUser@MultiTool zu BackupUser@192.168.1.100:bash
      sudo -u BackupUser ssh-keygen -t ed25519 -f /home/BackupUser/.ssh/id_ed25519
    • sudo -u BackupUser ssh-copy-id BackupUser@192.168.1.100
  2. NAS-Credentials:
    • Datei: /home/BackupUser/nas-credentials:
      username=BackupUser
    • password=rmb141161
    • Berechtigungen:bash
      sudo chown BackupUser:BackupUser /home/BackupUser/nas-credentials
    • sudo chmod 600 /home/BackupUser/nas-credentials
  3. Sudo-Rechte:
    • Datei: /etc/sudoers:
      BackupUser ALL=(ALL) NOPASSWD: /bin/mount, /bin/umount, /bin/mkdir, /usr/bin/chown
  4. Cron-Job:
    • Täglich um Mitternacht:bash
      crontab -u BackupUser -e

      0 0 * * * /home/autostart/WPBackup.sh

Funktionsweise

Das Skript sichert täglich das WordPress-Verzeichnis und die Datenbank, speichert sie auf dem NAS und löscht alte Backups (älter als 7 Tage) nur montags. Es protokolliert alle Schritte in /mnt/nas/log/backup_<WOCHENTAG>.log.

Ablauf

  1. Initialisierung:
    • Ermittelt den aktuellen Wochentag (1-7, 1 = Montag).
    • Definiert Quell- und Zielverzeichnisse, Datenbankdetails und NAS-Parameter.
  2. Wake-on-LAN:
    • Prüft die Erreichbarkeit des NAS und sendet ein WOL-Paket, falls nötig.
  3. NAS-Mount:
    • Mountet das NAS mit CIFS und den Credentials von BackupUser.
  4. Backup:
    • Erstellt einen Datenbank-Dump auf RaspWordpress.
    • Kopiert das WordPress-Verzeichnis und den Dump mit rsync auf das NAS.
    • Montags: Vollständiges Backup; andere Tage: Inkrementell basierend auf dem Vortag.
  5. Aufräumen:
    • Löscht das temporäre Verzeichnis auf RaspWordpress.
    • Löscht alte Backups (nur Montags).
  6. Abschluss:
    • Sendet optional eine Status-E-Mail (falls ssmtp installiert).
    • Hängt das NAS ab.

Skriptdetails

Variablen

  • DATE: Wochentag (1-7).
  • SOURCE: Quellpfad (BackupUser@192.168.1.100:/var/www/html/ev-travel-blog/).
  • DEST: Zielpfad auf dem NAS (/mnt/nas/ev-travel-blog).
  • LOG: Log-Datei (/mnt/nas/log/backup_$DATE.log).
  • DB_*: Datenbankzugangsdaten.
  • REMOTE_TEMP_DIR: Temporäres Verzeichnis für den Dump (/mnt/ssd/backup_temp).
  • BACKUP_*: Benutzer und dessen UID/GID.
  • NAS_*: NAS-IP und MAC-Adresse.

Schritte im Detail

  1. Wake-on-LAN:bash
    if ! ping -c 5 $NAS_IP > /dev/null 2>&1; then
  2.     wakeonlan $NAS_MAC
  3.     sleep 45
  4. fi
    • Prüft mit ping, ob das NAS erreichbar ist. Falls nicht, sendet es ein WOL-Paket und wartet 45 Sekunden.
  5. NAS-Mount:bash
    sudo umount /mnt/nas 2>/dev/null
  6. sudo mkdir -p /mnt/nas
  7. sudo mount -t cifs //192.168.0.11/… /mnt/nas -o credentials=/home/BackupUser/nas-credentials,…
    • Hängt das NAS ab (falls bereits gemountet), erstellt den Mountpoint und mountet die Freigabe.
  8. Log-Initialisierung:bash
    sudo mkdir -p „$LOG_DIR“
  9. sudo chown $BACKUP_USER:$BACKUP_USER „$LOG_DIR“
  10. echo „DEBUG: Skript gestartet am $(date)“ > „$LOG“ 2>&1
    • Erstellt das Log-Verzeichnis und schreibt den Startzeitpunkt.
  11. Backup-Slot:bash
    BACKUP_SLOT=“backup_$DATE“
  12. sudo mkdir -p „$DEST/$BACKUP_SLOT“
  13. sudo chown $BACKUP_USER:$BACKUP_USER „$DEST/$BACKUP_SLOT“
    • Erstellt ein tagesbasiertes Verzeichnis (z. B. backup_1 für Montag).
  14. Datenbank-Dump:bash
    ssh $BACKUP_USER@$DB_HOST „mysqldump -h $DB_HOST -u $DB_USER -p’$DB_PASS‘ $DB_NAME > $DB_DUMP“
    • Erstellt einen Dump auf RaspWordpress im temporären Verzeichnis.
  15. Rsync:bash
    if [ „$DATE“ -eq 1 ]; then
  16.     rsync -avz –delete –copy-links -e „ssh -l $BACKUP_USER“ „$SOURCE“ „$DEST/$BACKUP_SLOT/“
  17. else
  18.     PREV_DATE=$((DATE – 1))
  19.     [ „$PREV_DATE“ -eq 0 ] && PREV_DATE=7
  20.     PREV_SLOT=“backup_$PREV_DATE“
  21.     if [ -d „$DEST/$PREV_SLOT“ ]; then
  22.         rsync -avz –delete –copy-links –link-dest=“$DEST/$PREV_SLOT“ -e „ssh -l $BACKUP_USER“ „$SOURCE“ „$DEST/$BACKUP_SLOT/“
  23.     else
  24.         rsync -avz –delete –copy-links -e „ssh -l $BACKUP_USER“ „$SOURCE“ „$DEST/$BACKUP_SLOT/“
  25.     fi
  26. fi
  27. rsync -avz -e „ssh -l $BACKUP_USER“ „$BACKUP_USER@$DB_HOST:$DB_DUMP“ „$DEST/$BACKUP_SLOT/“
    • Montags: Vollständiges Backup.
    • Andere Tage: Inkrementell mit Hardlinks zum Vortag (spart Speicherplatz).
    • Kopiert den Datenbank-Dump separat.
  28. Aufräumen:bash
    ssh $BACKUP_USER@$DB_HOST „rm -rf $REMOTE_TEMP_DIR“
  29. if [ „$DATE“ -eq 1 ]; then
  30.     cd „$DEST“ && find . -maxdepth 1 -type d -name „backup_*“ -mtime +7 -exec rm -rf {} \;
  31. fi
    • Löscht das temporäre Verzeichnis.
    • Löscht alte Backups nur Montags.
  32. E-Mail und Unmount:bash
    if command -v ssmtp >/dev/null 2>&1; then
  33.     echo -e „Subject: Backup Status $DATE\n\n$STATUS“ | ssmtp dein.email@gmail.com
  34. fi
  35. cd /
  36. sudo umount -f /mnt/nas
    • Sendet eine E-Mail (falls konfiguriert).
    • Hängt das NAS ab (erzwingt bei Bedarf).

Fehlerbehandlung

  • Bei Fehlern (z. B. Mount oder Datenbankzugriff) wird das Skript abgebrochen und das NAS abgehängt.
  • Warnungen (z. B. beim Löschen von $REMOTE_TEMP_DIR) werden protokolliert, brechen aber nicht ab.

Ausführung

  • Manuell:bash
    sudo -u BackupUser /home/autostart/WPBackup.sh
  • Automatisch via Cron:
    0 0 * * * /home/autostart/WPBackup.sh

Log-Datei

  • Pfad: /mnt/nas/log/backup_$DATE.log.
  • Beispiel:
    DEBUG: Skript gestartet am Mon 31 Mar 20:20:12 CEST 2025
  • DEBUG: NAS erfolgreich gemountet
  • DEBUG: Rsync Dateien von BackupUser@192.168.1.100:/var/www/html/ev-travel-blog/ nach /mnt/nas/ev-travel-blog/backup_1/

Anpassungen

  • Vollständiger Pfad: Ändere SOURCE zu einem anderen Verzeichnis, falls nötig.
  • E-Mail: Installiere ssmtp und konfiguriere es für Benachrichtigungen.
  • Laufzeit: Passe sleep 45 an, falls das NAS länger braucht.

Das war’s! Du hast jetzt ein robustes Backup-Skript mit WOL und inkrementeller Logik. Wenn du noch Fragen hast oder etwas ergänzen möchtest, lass es mich wissen!

So sieht es aus, wenn das Skript läuft:

ralf@MultiTool:/home $ sudo -u BackupUser /home/autostart/WPBackup.sh
++ date +%u

  • DATE=1
  • SOURCE=BackupUser@192.168.1.100:/var/www/html/ev-travel-blog/
  • DEST=/mnt/nas/ev-travel-blog
  • LOG_DIR=/mnt/nas/log
  • LOG=/mnt/nas/log/backup_1.log
  • DB_USER=BackupUser
  • DB_PASS=backup-user-passwort
  • DB_NAME=dbs10597143
  • DB_HOST=192.168.1.100
  • REMOTE_TEMP_DIR=/mnt/ssd/backup_temp
  • DB_DUMP=/mnt/ssd/backup_temp/db_backup_1.sql
  • BACKUP_USER=BackupUser
    ++ id -u BackupUser
  • BACKUP_UID=1001
    ++ id -g BackupUser
  • BACKUP_GID=1001
  • NAS_IP=192.168.0.11
  • NAS_MAC=00:11:32:F1:56:17
  • echo ‚DEBUG: Prüfe NAS-Erreichbarkeit und sende WOL, falls nötig‘
  • ping -c 5 192.168.0.11
  • sudo umount /mnt/nas
  • sudo mkdir -p /mnt/nas
  • sudo mount -t cifs //192.168.0.11/ScharpNAS/data/Daten_II/Backup/Raspberry/100_PI_WordPress /mnt/nas -o credentials=/home/BackupUser/nas-credentials,uid=1001,gid=1001,dir_mode=0777,file_mode=0666
  • sudo mkdir -p /mnt/nas/log
  • sudo chown BackupUser:BackupUser /mnt/nas/log
    ++ date
  • echo ‚DEBUG: Skript gestartet am Mon 31 Mar 20:30:30 CEST 2025‘
  • echo ‚DEBUG: NAS erfolgreich gemountet‘
  • BACKUP_SLOT=backup_1
  • echo ‚DEBUG: Backup-Slot: backup_1‘
  • echo ‚DEBUG: Erstelle Verzeichnis: /mnt/nas/ev-travel-blog/backup_1‘
  • sudo mkdir -p /mnt/nas/ev-travel-blog/backup_1
  • sudo chown BackupUser:BackupUser /mnt/nas/ev-travel-blog/backup_1
  • echo ‚DEBUG: Erstelle temporäres Verzeichnis auf 192.168.1.100: /mnt/ssd/backup_temp‘
  • ssh BackupUser@192.168.1.100 ‚mkdir -p /mnt/ssd/backup_temp‘
  • ‚[‚ 0 -ne 0 ‚]‘
  • echo ‚DEBUG: Teste MySQL-Zugang auf 192.168.1.100‘
  • ssh BackupUser@192.168.1.100 ‚mysql -h 192.168.1.100 -u BackupUser -p’\“backup-user-passwort’\“ -e ‚\“SHOW DATABASES;’\“‘
    Database
    dbs10597143
    information_schema
  • ‚[‚ 0 -ne 0 ‚]‘
  • echo ‚DEBUG: Erstelle Datenbank-Dump: /mnt/ssd/backup_temp/db_backup_1.sql‘
  • ssh BackupUser@192.168.1.100 ‚mysqldump -h 192.168.1.100 -u BackupUser -p’\“backup-user-passwort’\“ dbs10597143 > /mnt/ssd/backup_temp/db_backup_1.sql‘
  • ‚[‚ 0 -eq 0 ‚]‘
  • echo ‚DEBUG: Datenbank-Backup erfolgreich erstellt: /mnt/ssd/backup_temp/db_backup_1.sql‘
  • echo ‚DEBUG: Rsync Dateien von BackupUser@192.168.1.100:/var/www/html/ev-travel-blog/ nach /mnt/nas/ev-travel-blog/backup_1/‘
  • ‚[‚ 1 -eq 1 ‚]‘
  • rsync -avz –delete –copy-links -e ’ssh -l BackupUser‘ BackupUser@192.168.1.100:/var/www/html/ev-travel-blog/ /mnt/nas/ev-travel-blog/backup_1/
    + echo ‚DEBUG: Rsync Datenbank-Dump von 192.168.1.100 nach /mnt/nas/ev-travel-blog/backup_1/‘
  • rsync -avz -e ’ssh -l BackupUser‘ BackupUser@192.168.1.100:/mnt/ssd/backup_temp/db_backup_1.sql /mnt/nas/ev-travel-blog/backup_1/
  • echo ‚DEBUG: Lösche temporäres Verzeichnis auf 192.168.1.100: /mnt/ssd/backup_temp‘
  • ssh BackupUser@192.168.1.100 ‚rm -rf /mnt/ssd/backup_temp‘
  • ‚[‚ 0 -ne 0 ‚]‘
  • echo ‚DEBUG: Lösche alte Backups in /mnt/nas/ev-travel-blog‘
  • ‚[‚ 1 -eq 1 ‚]‘
  • cd /mnt/nas/ev-travel-blog
  • find . -maxdepth 1 -type d -name ‚backup_*‘ -mtime +7 -exec rm -rf ‚{}‘ ‚;‘
  • STATUS=’Backup vom 1 abgeschlossen. Details in /mnt/nas/log/backup_1.log.‘
  • echo ‚DEBUG: Sende Status-E-Mail (wenn ssmtp verfügbar)‘
  • command -v ssmtp
    ++ date
  • echo ‚DEBUG: Skript beendet am Mon 31 Mar 20:52:43 CEST 2025‘
  • echo ‚DEBUG: Unmount NAS‘
  • cd /
  • sudo umount -f /mnt/nas

Und das erstellt dann ein Log Datei, die im nächsten schritt per E-Mail versendet wird. Oder auch nur das Ergebnis nach Fehlern in der log Datei. Alles ist mit der KI möglich…

DEBUG: Skript gestartet am Mon 31 Mar 20:30:30 CEST 2025
DEBUG: NAS erfolgreich gemountet
DEBUG: Backup-Slot: backup_1
DEBUG: Erstelle Verzeichnis: /mnt/nas/ev-travel-blog/backup_1
DEBUG: Erstelle temporäres Verzeichnis auf 192.168.1.100: /mnt/ssd/backup_temp
DEBUG: Teste MySQL-Zugang auf 192.168.1.100
DEBUG: Erstelle Datenbank-Dump: /mnt/ssd/backup_temp/db_backup_1.sql
DEBUG: Datenbank-Backup erfolgreich erstellt: /mnt/ssd/backup_temp/db_backup_1.sql
DEBUG: Rsync Dateien von BackupUser@192.168.1.100:/var/www/html/ev-travel-blog/ nach /mnt/nas/ev-travel-blog/backup_1/
receiving incremental file list
deleting user/user-edit.php
deleting user/profile.php
deleting user/privacy.php
deleting user/menu.php
deleting user/index.php
deleting user/freedoms.php
deleting user/credits.php
deleting user/contribute.php
deleting user/admin.php
deleting user/about.php
deleting user/
deleting network/users.php
deleting network/user-new.php
deleting network/user-edit.php
deleting network/upgrade.php
deleting network/update.php
deleting network/update-core.php
deleting network/themes.php
deleting network/theme-install.php
deleting network/theme-editor.php
deleting network/sites.php
deleting network/site-users.php
deleting network/site-themes.php
deleting network/site-settings.php
deleting network/site-new.php
deleting network/site-info.php
deleting network/setup.php
deleting network/settings.php
deleting network/profile.php
deleting network/privacy.php
deleting network/plugins.php
deleting network/plugin-install.php
deleting network/plugin-editor.php
deleting network/menu.php
deleting network/index.php
deleting network/freedoms.php
deleting network/edit.php
deleting network/credits.php
deleting network/contribute.php
:
:
wp-includes/theme-compat/comments.php
wp-includes/theme-compat/embed-404.php
wp-includes/theme-compat/embed-content.php
wp-includes/theme-compat/embed.php
wp-includes/theme-compat/footer-embed.php
wp-includes/theme-compat/footer.php
wp-includes/theme-compat/header-embed.php
wp-includes/theme-compat/header.php
wp-includes/theme-compat/sidebar.php
wp-includes/widgets/
wp-includes/widgets/class-wp-nav-menu-widget.php
wp-includes/widgets/class-wp-widget-archives.php
wp-includes/widgets/class-wp-widget-block.php
wp-includes/widgets/class-wp-widget-calendar.php
wp-includes/widgets/class-wp-widget-categories.php
wp-includes/widgets/class-wp-widget-custom-html.php
wp-includes/widgets/class-wp-widget-links.php
wp-includes/widgets/class-wp-widget-media-audio.php
wp-includes/widgets/class-wp-widget-media-gallery.php
wp-includes/widgets/class-wp-widget-media-image.php
wp-includes/widgets/class-wp-widget-media-video.php
wp-includes/widgets/class-wp-widget-media.php
wp-includes/widgets/class-wp-widget-meta.php
wp-includes/widgets/class-wp-widget-pages.php
wp-includes/widgets/class-wp-widget-recent-comments.php
wp-includes/widgets/class-wp-widget-recent-posts.php
wp-includes/widgets/class-wp-widget-rss.php
wp-includes/widgets/class-wp-widget-search.php
wp-includes/widgets/class-wp-widget-tag-cloud.php
wp-includes/widgets/class-wp-widget-text.php

sent 1,456,441 bytes received 30,720,391,923 bytes 23,265,314.93 bytes/sec
total size is 31,014,962,453 speedup is 1.01
DEBUG: Rsync Datenbank-Dump von 192.168.1.100 nach /mnt/nas/ev-travel-blog/backup_1/
receiving incremental file list
db_backup_1.sql

sent 43 bytes received 4,116,951 bytes 633,383.69 bytes/sec
total size is 249,271,598 speedup is 60.55
DEBUG: Lösche temporäres Verzeichnis auf 192.168.1.100: /mnt/ssd/backup_temp
DEBUG: Lösche alte Backups in /mnt/nas/ev-travel-blog
DEBUG: Sende Status-E-Mail (wenn ssmtp verfügbar)
DEBUG: Skript beendet am Mon 31 Mar 20:52:43 CEST 2025
DEBUG: Unmount NAS
umount: /mnt/nas: target is busy.

Das ist die Auslastung des Rechners 192.168.0.16 (MultiTool), der das Backup initiert, und die Dateien zum NAS kopiert:

Die beiden roten Spitzen sind der Backup Vorgang.

Kommentar verfassen

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Nach oben scrollen