Metainformationen zur Seite
  •  

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

Nächste Überarbeitung
Vorhergehende Überarbeitung
magicmirror:magicmirror_tipps:backup [07.10.2026] – angelegt koljamagicmirror:magicmirror_tipps:backup [08.10.2026] (aktuell) – kolja
Zeile 1: Zeile 1:
-====== Backup auf ein NAS ======+====== MagicMirror – Backup auf NAS ======
  
 ===== Ziel ===== ===== Ziel =====
  
-Der komplette relevante MagicMirror-Ordner eines Raspberry Pi wird manuell auf einem NAS gesichert.+Der MagicMirror-Ordner wird auf ein NAS gesichert.
  
-Jedes Backup wird als komprimiertes TAR.GZ-Archiv gespeichert.+Es gibt zwei Varianten:
  
-Das Backup:+  * **Manuelles Backup:** Start bei Bedarf per Befehl 
 +  * **Automatisches Backup:** jeden Sonntag um 01:00 Uhr
  
-  * wird ausschließlich manuell gestartet +Eigenschaften:
-  * läuft nach dem Start im Hintergrund weiter +
-  * erhält einen Ordner mit Datum und Uhrzeit +
-  * wird komprimiert gespeichert +
-  * wird nach Erstellung vollständig geprüft +
-  * erhält zusätzlich eine SHA-256-Prüfsumme +
-  * wird nur gestartet, wenn das richtige NAS tatsächlich gemountet ist +
-  * bleibt bei einem Fehler als ''_INCOMPLETE'' gekennzeichnet +
-  * verhindert zwei gleichzeitig laufende Backups+
  
-Nicht gesichert werden:+  * Backup als komprimiertes ''tar.gz'' 
 +  * ''node_modules'' werden nicht gesichert 
 +  * SHA-256-Prüfsumme zur Integritätskontrolle 
 +  * NAS muss tatsächlich erreichbar und gemountet sein 
 +  * unvollständige Backups bleiben als ''_INCOMPLETE'' erhalten 
 +  * automatische Backups: maximal **4 Stück** 
 +  * Erfolg/Fehler wird über **ioBroker → Telegram** gemeldet
  
-<code> +===== Verwendete Pfade =====
-node_modules +
-</code>+
  
-''node_modules'' enthalten installierte Node.js-Abhängigkeiten. 
  
-Diese sollten insbesondere nach einem Wechsel auf einen neuen Raspberry Pi, eine andere Node.js-Version oder ein neues Betriebssystem neu installiert werden.+^ Funktion ^ Pfad / Ort ^ 
 +| Manuelles Backup-Script | ''/home/pi/bin/backup_magicmirror.sh'' | 
 +| Wöchentliches Backup-Script | ''/home/pi/bin/backup_magicmirror_weekly.sh'' | 
 +| ioBroker-Zugangsdaten | ''/home/pi/.config/magicmirror-backup/iobroker.conf'' | 
 +| Backup-Logs | ''/home/pi/magicmirror-backup-logs/'' | 
 +| systemd-Service | ''/etc/systemd/system/magicmirror-backup-weekly.service'' | 
 +| systemd-Timer | ''/etc/systemd/system/magicmirror-backup-weekly.timer'' | 
 +| NAS-Zugangsdaten | ''/etc/samba/credentials-nasbackup'' | 
 +| NAS-Mount-Konfiguration | ''/etc/fstab'' | 
 +| NAS-Mountpunkt | ''/mnt/nasbackup'' | 
 +| Manuelle Backups | ''/mnt/nasbackup/Manuelle_Backups/'' | 
 +| Automatische Backups | ''/mnt/nasbackup/Automatische_Backups/'' | 
 +| ioBroker Telegram-Script | ''ioBroker → Skripte → JavaScript'' | 
 +| ioBroker Backup-Datenpunkte | ''0_userdata.0.MagicMirror.Backup.*'' |
  
  
-====== Backup-Struktur ======+====== 1. NAS auf dem Raspberry Pi einbinden ======
  
-Beispiel:+===== Pakete installieren =====
  
-<code> +<code bash> 
-NAS +sudo apt update 
-└── Backup-Freigabe +sudo apt install cifs-utils
-    └── Manuelle_Backups +
-        ├── MagicMirror_2026-10-07_12-30-00 +
-        │   ├── MagicMirror.tar.gz +
-        │   └── MagicMirror.tar.gz.sha256 +
-        │ +
-        └── MagicMirror_2026-11-01_18-42-10 +
-            ├── MagicMirror.tar.gz +
-            └── MagicMirror.tar.gz.sha256+
 </code> </code>
  
  
-====== Platzhalter dieser Anleitung ======+===== Gruppe anlegen =====
  
-^ Platzhalter ^ Bedeutung ^ +<code bash> 
-| ''<PI_USER>'' | Benutzer auf dem Raspberry Pi | +sudo groupadd nasusers 
-| ''<NAS_HOST>'' | IP-Adresse oder DNS-Name des NAS | +sudo usermod -aG nasusers <PI_USER> 
-| ''<NAS_SHARE>'' | SMB-Freigabe auf dem NAS | +</code>
-| ''<NAS_USER>'' | Benutzername auf dem NAS | +
-| ''<NAS_PASSWORT>'' | Passwort des NAS-Benutzers | +
-| ''<UID>'' | numerische Benutzer-ID des Pi-Benutzers | +
-| ''<GID>'' | numerische Gruppen-ID der Gruppe ''nasusers'' | +
- +
- +
-====== Vorbereitung auf einem neuen Raspberry Pi ====== +
- +
-===== 1. Benutzer einrichten =====+
  
-Bei Raspberry Pi OS wird normalerweise bereits bei der Installation ein Benutzer angelegt.+Danach neu anmelden oder neu starten.
  
-Falls ein zusätzlicher Benutzer benötigt wird:+UID und GID ermitteln:
  
 <code bash> <code bash>
-sudo adduser <PI_USER>+id -u <PI_USER> 
 +getent group nasusers
 </code> </code>
  
-Optional sudo-Rechte vergeben:+ 
 +===== Mountpunkt anlegen =====
  
 <code bash> <code bash>
-sudo usermod -aG sudo <PI_USER>+sudo mkdir -p /mnt/nasbackup
 </code> </code>
  
-Kontrolle:+ 
 +===== NAS-Zugangsdaten speichern =====
  
 <code bash> <code bash>
-id <PI_USER>+sudo mkdir -p /etc/samba 
 +sudo nano /etc/samba/credentials-nasbackup
 </code> </code>
  
 +Inhalt:
  
-===== 2. NAS-Gruppe anlegen ===== +<code> 
- +username=<NAS_USER> 
-<code bash> +password=<NAS_PASSWORT>
-sudo groupadd nasusers+
 </code> </code>
  
-Benutzer hinzufügen:+Datei schützen:
  
 <code bash> <code bash>
-sudo usermod -aG nasusers <PI_USER>+sudo chown root:root /etc/samba/credentials-nasbackup 
 +sudo chmod 600 /etc/samba/credentials-nasbackup
 </code> </code>
  
-Anschließend neu anmelden oder den Raspberry Pi neu starten. 
  
-Kontrolle:+===== /etc/fstab ===== 
 + 
 +Vorher sichern:
  
 <code bash> <code bash>
-getent group nasusers +sudo cp /etc/fstab /etc/fstab.backup 
-id <PI_USER>+sudo nano /etc/fstab
 </code> </code>
  
 +Eintrag:
  
-===== 3. UID und GID ermitteln =====+<code> 
 +//<NAS_HOST>/<NAS_SHARE> /mnt/nasbackup cifs credentials=/etc/samba/credentials-nasbackup,vers=3.0,iocharset=utf8,uid=<UID>,gid=<GID>,file_mode=0660,dir_mode=0770,_netdev,nofail,x-systemd.automount,x-systemd.mount-timeout=10s 0 0 
 +</code>
  
-UID:+systemd neu laden:
  
 <code bash> <code bash>
-id -u <PI_USER>+sudo systemctl daemon-reload 
 +sudo systemctl start mnt-nasbackup.automount
 </code> </code>
  
-GID:+Status:
  
 <code bash> <code bash>
-getent group nasusers+systemctl status mnt-nasbackup.automount --no-pager
 </code> </code>
  
-Beispiel:+Erwartet:
  
 <code> <code>
-nasusers:x:1003:<PI_USER>+Active: active (waiting)
 </code> </code>
  
-In diesem Beispiel wäre: 
  
-<code> +===== NAS testen =====
-GID = 1003 +
-</code>+
  
- +Mount auslösen:
-===== 4. CIFS-Unterstützung installieren =====+
  
 <code bash> <code bash>
-sudo apt update +ls -la /mnt/nasbackup
-sudo apt install cifs-utils+
 </code> </code>
  
-Ein Samba-Server wird nicht benötigt.+Prüfen:
  
-Der Raspberry Pi greift lediglich als SMB/CIFS-Client auf das NAS zu.+<code bash> 
 +findmnt /mnt/nasbackup 
 +df -h /mnt/nasbackup 
 +</code>
  
- +Schreibtest:
-===== 5. Mountpunkt erstellen =====+
  
 <code bash> <code bash>
-sudo mkdir -p /mnt/nasbackup+touch /mnt/nasbackup/test.txt 
 +rm /mnt/nasbackup/test.txt
 </code> </code>
  
  
-===== 6. Zugangsdaten zum NAS speichern =====+====== 2. Manuelles MagicMirror-Backup ======
  
-Verzeichnis anlegen:+Das manuelle Backup:
  
-<code bash> +  * wird per Befehl gestartet 
-sudo mkdir -p /etc/samba +  * läuft danach im Hintergrund 
-</code>+  * erzeugt ein geprüftes TAR.GZ-Archiv 
 +  * erzeugt zusätzlich eine SHA-256-Prüfsumme 
 +  * sichert keine ''node_modules'' 
 +  * bricht ab, wenn das NAS nicht korrekt gemountet ist 
 +  * meldet Erfolg oder Fehler über ioBroker / Telegram
  
-Datei erstellen:+Die ioBroker-Zugangsdaten werden aus
  
-<code bash> +<code> 
-sudo nano /etc/samba/credentials-nasbackup+~/.config/magicmirror-backup/iobroker.conf
 </code> </code>
  
-Inhalt:+gelesen.
  
-<code> 
-username=<NAS_USER> 
-password=<NAS_PASSWORT> 
-</code> 
  
-Optional:+===== Script ===== 
 + 
 +Das Script liegt unter:
  
 <code> <code>
-domain=WORKGROUP+~/bin/backup_magicmirror.sh
 </code> </code>
  
-Datei absichern:+Bearbeiten:
  
 <code bash> <code bash>
-sudo chown root:root /etc/samba/credentials-nasbackup +nano ~/bin/backup_magicmirror.sh
-sudo chmod 600 /etc/samba/credentials-nasbackup+
 </code> </code>
  
-Kontrolle:+Das Script besitzt intern zwei wichtige Betriebsarten:
  
-<code bash> +^ Modus ^ Verwendung ^ 
-ls -l /etc/samba/credentials-nasbackup +| ''--worker'' | erstellt ausschließlich das Backup; wird auch vom automatischen Weekly-Backup verwendet | 
-</code>+| ''--manual-worker'' | führt den Backup-Worker aus und meldet anschließend Erfolg oder Fehler an ioBroker |
  
-Erwartet:+Dadurch erzeugt das automatische Backup keine doppelte Telegram-Nachricht.
  
-<code> + 
--rw------- 1 root root ...+===== Backup starten ===== 
 + 
 +<code bash> 
 +~/bin/backup_magicmirror.sh
 </code> </code>
  
 +Das Backup läuft anschließend im Hintergrund.
  
-===== 7. NAS in /etc/fstab eintragen ===== 
  
-Vorher Sicherung:+===== Status / Log ansehen =====
  
 <code bash> <code bash>
-sudo cp /etc/fstab /etc/fstab.backup+tail -f "$(ls -t ~/magicmirror-backup-logs/*.log | head -1)"
 </code> </code>
  
-Bearbeiten:+Mit ''Ctrl+C'' wird nur die Log-Anzeige beendet.
  
-<code bash> +Das Backup selbst läuft weiter. 
-sudo nano /etc/fstab+ 
 + 
 +===== Erfolgreiches Backup ===== 
 + 
 +Ein erfolgreiches Backup enthält: 
 + 
 +<code> 
 +MagicMirror.tar.gz 
 +MagicMirror.tar.gz.sha256
 </code> </code>
  
-Eintrag:+Das Log enthält:
  
 <code> <code>
-//<NAS_HOST>/<NAS_SHARE> /mnt/nasbackup cifs credentials=/etc/samba/credentials-nasbackup,vers=3.0,iocharset=utf8,uid=<UID>,gid=<GID>,file_mode=0660,dir_mode=0770,_netdev,nofail,x-systemd.automount,x-systemd.mount-timeout=10s 0 0+BACKUP ERFOLGREICH
 </code> </code>
  
 +Zusätzlich wird über ioBroker eine Telegram-Nachricht gesendet.
  
-===== Bedeutung der Mount-Optionen ===== 
  
-^ Option ^ Bedeutung ^ +===== Speicherort =====
-| ''credentials=...'' | NAS-Zugangsdaten liegen in einer geschützten Datei | +
-| ''vers=3.0'' | SMB 3 verwenden | +
-| ''uid=<UID>'' | lokaler Eigentümer der Dateien | +
-| ''gid=<GID>'' | lokale Gruppe der Dateien | +
-| ''file_mode=0660'' | Lese-/Schreibzugriff für Benutzer und Gruppe | +
-| ''dir_mode=0770'' | Zugriff auf Verzeichnisse für Benutzer und Gruppe | +
-| ''_netdev'' | Netzwerk-Dateisystem | +
-| ''nofail'' | Boot funktioniert auch bei ausgeschaltetem NAS | +
-| ''x-systemd.automount'' | NAS wird erst bei tatsächlichem Zugriff gemountet | +
-| ''x-systemd.mount-timeout=10s'' | begrenzt die Mount-Wartezeit |+
  
 +<code>
 +/mnt/nasbackup/Manuelle_Backups/
 +</code>
  
-===== 8. Automount aktivieren =====+Beispiel:
  
-<code bash> +<code> 
-sudo systemctl daemon-reload +MagicMirror_2026-10-08_21-30-00/ 
-sudo systemctl start mnt-nasbackup.automount+├── MagicMirror.tar.gz 
 +└── MagicMirror.tar.gz.sha256
 </code> </code>
  
-Status:+ 
 +===== Backup prüfen =====
  
 <code bash> <code bash>
-systemctl status mnt-nasbackup.automount --no-pager -l+cd /mnt/nasbackup/Manuelle_Backups/MagicMirror_YYYY-MM-DD_HH-MM-SS 
 + 
 +sha256sum -c MagicMirror.tar.gz.sha256
 </code> </code>
  
-Korrekt:+Erwartet:
  
 <code> <code>
-Active: active (waiting)+MagicMirror.tar.gz: OK
 </code> </code>
  
  
-===== 9. NAS-Verbindung testen =====+====== 3. ioBroker für Backup-Meldungen ======
  
-Mount durch Zugriff auslösen:+===== REST-API =====
  
-<code bash> +In ioBroker den Adapter **REST API** installieren.
-ls -la /mnt/nasbackup +
-</code>+
  
-Prüfen:+Empfohlene Einstellungen:
  
-<code bash> +  * Authentifizierung: **Ein** 
-findmnt /mnt/nasbackup +  * Keine GUI: **Ein** 
-</code>+  * Commands erlauben: **Aus** 
 +  * Admin-Commands erlauben: **Aus** 
 +  * API nur im internen Netzwerk erreichbar machen 
 +  * kein Port-Forwarding ins Internet
  
-Es muss ein CIFS-Eintrag für den erwarteten Share vorhanden sein. 
  
 +===== Benutzer und Gruppe =====
  
-===== 10. Speicherplatz prüfen =====+ioBroker-Benutzer anlegen:
  
-<code bash> +<code> 
-df -h /mnt/nasbackup+magicmirror
 </code> </code>
  
 +Gruppe anlegen:
  
-===== 11. Schreibzugriff prüfen ===== +<code> 
- +magicmirror_backup
-<code bash> +
-touch /mnt/nasbackup/test_backup.txt +
-ls -l /mnt/nasbackup/test_backup.txt +
-rm /mnt/nasbackup/test_backup.txt+
 </code> </code>
  
-Erst wenn dieser Test funktioniert, das Backup-Script einrichten.+Benutzer der Gruppe hinzufügen.
  
 +Benötigte Gruppenrechte:
  
-====== Backup-Script einrichten ======+  * Objekte: Auflisten + Lesen 
 +  * Zustände: Auflisten + Lesen + Schreiben 
 +  * HTTP: Ein 
 +  * Execute/SendTo: Aus
  
-===== 1. Script-Verzeichnis anlegen ===== 
  
-<code bash> +===== Datenpunkte ===== 
-mkdir -p ~/bin+ 
 +Folgende Datenpunkte werden benötigt: 
 + 
 +<code> 
 +0_userdata.0.MagicMirror.Backup.Status 
 +0_userdata.0.MagicMirror.Backup.Message 
 +0_userdata.0.MagicMirror.Backup.LastRun 
 +0_userdata.0.MagicMirror.Backup.BackupPath
 </code> </code>
  
 +Wichtig:
  
-===== 2. Script erstellen =====+Der Benutzer ''magicmirror'' sollte Besitzer dieser vier Datenpunkte sein. 
 + 
 +Beispiel auf dem ioBroker-Host:
  
 <code bash> <code bash>
-nano ~/bin/backup_magicmirror.sh+iobroker object chown magicmirror magicmirror_backup 0_userdata.0.MagicMirror.Backup.Status 
 +iobroker object chown magicmirror magicmirror_backup 0_userdata.0.MagicMirror.Backup.Message 
 +iobroker object chown magicmirror magicmirror_backup 0_userdata.0.MagicMirror.Backup.LastRun 
 +iobroker object chown magicmirror magicmirror_backup 0_userdata.0.MagicMirror.Backup.BackupPath
 </code> </code>
  
-Inhalt: 
  
-<code bash> +===== Telegram-JavaScript =====
-#!/usr/bin/env bash+
  
-SOURCE="$HOME/MagicMirror" +Im ioBroker-JavaScript-Adapter:
-NAS="/mnt/nasbackup" +
-BACKUP_BASE="$NAS/Manuelle_Backups" +
-LOGDIR="$HOME/magicmirror-backup-logs"+
  
-# An eigenes NAS anpassen: +<code javascript> 
-EXPECTED_SOURCE="//<NAS_HOST>/<NAS_SHARE>"+const BASE = '0_userdata.0.MagicMirror.Backup';
  
 +createState(`${BASE}.Status`, 'idle', {
 +    type: 'string',
 +    role: 'text',
 +    read: true,
 +    write: true
 +});
  
-check_nas() {+createState(`${BASE}.Message`, '', { 
 +    type: 'string', 
 +    role: 'text', 
 +    read: true, 
 +    write: true 
 +});
  
-    if ! timeout 15s stat "$NAS" >/dev/null 2>&1; then +createState(`${BASE}.LastRun`, '', { 
-        echo "FEHLER: NAS ist nicht erreichbar." +    type: 'string', 
-        return 1 +    role: 'text', 
-    fi+    read: true, 
 +    write: true 
 +});
  
-    MOUNT_INFO="$(findmnt -T "$NAS" -n -o FSTYPE,SOURCE | tail -n 1)"+createState(`${BASE}.BackupPath`, '', { 
 +    type: 'string', 
 +    role: 'text', 
 +    read: true, 
 +    write: true 
 +});
  
-    FSTYPE="$(awk '{print $1}' <<< "$MOUNT_INFO")" 
-    MOUNT_SOURCE="$(awk '{print $2}' <<< "$MOUNT_INFO")" 
  
-    if [[ "$FSTYPE" != "cifs" || "$MOUNT_SOURCE" != "$EXPECTED_SOURCE" ]]; then +on({ 
-        echo "FEHLER: NAS-Share ist nicht korrekt eingebunden." +    id: `${BASE}.Status`, 
-        echo "Gefunden: $MOUNT_INFO" +    change: 'ne' 
-        return 1 +}, obj => {
-    fi+
  
-    return 0 +    const status = String(obj.state.val);
-}+
  
 +    if (status !== 'success' && status !== 'error') return;
  
-if [[ "${1:-}" == "--worker" ]]; then+    const message = String(getState(`${BASE}.Message`).val || ''); 
 +    const lastRun = String(getState(`${BASE}.LastRun`).val || ''); 
 +    const backupPath = String(getState(`${BASE}.BackupPath`).val || '');
  
-    FINAL_DEST="$2" +    let text;
-    TEMP_DEST="${FINAL_DEST}_INCOMPLETE"+
  
-    ARCHIVE="$TEMP_DEST/MagicMirror.tar.gz" +    if (status === 'success') { 
-    CHECKSUM="$TEMP_DEST/MagicMirror.tar.gz.sha256"+        text = `✅ MagicMirror Backup erfolgreich\n\n${message}`; 
 +    } else { 
 +        text = `❌ MagicMirror Backup FEHLGESCHLAGEN\n\n${message}`; 
 +    }
  
 +    text += `\n\nZeit: ${lastRun}`;
  
-    # Nur ein Backup gleichzeitig. +    if (backupPath) { 
-    exec 9>/tmp/magicmirror-backup.lock+        text += `\nBackup: ${backupPath}`; 
 +    }
  
-    if ! flock -n 9; then +    sendTo('telegram.0', text); 
-        echo "FEHLER: Es läuft bereits ein MagicMirror-Backup." +}); 
-        exit 1 +</code>
-    fi+
  
  
-    echo +====== 4. Zugangsdaten für ioBroker auf dem Pi ======
-    echo "==================================================" +
-    echo "MagicMirror Backup" +
-    echo "Start:  $(date)" +
-    echo "Quelle: $SOURCE" +
-    echo "Ziel:   $FINAL_DEST" +
-    echo "==================================================" +
-    echo+
  
 +<code bash>
 +mkdir -p ~/.config/magicmirror-backup
 +nano ~/.config/magicmirror-backup/iobroker.conf
 +</code>
  
-    if ! check_nas; then +Inhalt:
-        echo "BACKUP ABGEBROCHEN: NAS nicht verfügbar." +
-        exit 2 +
-    fi+
  
 +<code bash>
 +IOBROKER_URL='http://<IOBROKER_HOST>:<REST_PORT>'
 +IOBROKER_USER='magicmirror'
 +IOBROKER_PASSWORD='<PASSWORT>'
 +</code>
  
-    mkdir -p "$TEMP_DEST" || exit 3+Datei schützen:
  
 +<code bash>
 +chmod 600 ~/.config/magicmirror-backup/iobroker.conf
 +</code>
  
-    echo "Erstelle MagicMirror-Archiv ..." 
-    echo "node_modules werden bewusst NICHT gesichert." 
-    echo 
  
 +====== 5. Automatisches wöchentliches Backup ======
  
-    tar \ +===== Script =====
-        --create \ +
-        --gzip \ +
-        --dereference \ +
-        --exclude='MagicMirror/node_modules' \ +
-        --exclude='MagicMirror/node_modules/*' \ +
-        --exclude='*/node_modules' \ +
-        --exclude='*/node_modules/*' \ +
-        --file="$ARCHIVE" \ +
-        --directory="$HOME" \ +
-        MagicMirror+
  
-    RESULT=$?+<code bash> 
 +nano ~/bin/backup_magicmirror_weekly.sh 
 +</code>
  
 +Inhalt:
  
-    if [[ $RESULT -ne 0 ]]; then+<code bash> 
 +#!/usr/bin/env bash
  
-        echo +BACKUP_SCRIPT="$HOME/bin/backup_magicmirror.sh"
-        echo "BACKUP FEHLGESCHLAGEN" +
-        echo "tar Fehlercode: $RESULT" +
-        echo "Unvollständiges Backup:" +
-        echo "$TEMP_DEST"+
  
-        exit "$RESULT" +NAS="/mnt/nasbackup" 
-    fi+AUTO_BASE="$NAS/Automatische_Backups"
  
 +LOGDIR="$HOME/magicmirror-backup-logs"
  
-    echo +CONFIG="$HOME/.config/magicmirror-backup/iobroker.conf"
-    echo "Prüfe gzip ..."+
  
-    if ! gzip -t "$ARCHIVE"; then +KEEP_BACKUPS=4
-        echo "FEHLER: gzip-Prüfung fehlgeschlagen." +
-        exit 4 +
-    fi+
  
-    echo "gzip: OK"+STATE_BASE="0_userdata.0.MagicMirror.Backup"
  
  
-    echo +if [[ ! -r "$CONFIG" ]]; then 
-    echo "Prüfe TAR ..."+    echo "FEHLER: $CONFIG fehlt." 
 +    exit 1 
 +fi
  
-    if ! tar -tzf "$ARCHIVE" >/dev/null; then +source "$CONFIG"
-        echo "FEHLER: TAR-Prüfung fehlgeschlagen." +
-        exit 5 +
-    fi+
  
-    echo "tar: OK" 
  
 +set_iobroker_state() {
  
-    echo +    local ID="$1" 
-    echo "Erzeuge SHA-256-Prüfsumme ..."+    local VALUE="$2"
  
-    ( +    curl \ 
-        cd "$TEMP_DEST" || exit 1 +        --fail \ 
-        sha256sum MagicMirror.tar.gz > MagicMirror.tar.gz.sha256 +        --silent \ 
-    ) || exit 6+        --show-error \ 
 +        --max-time 10 \ 
 +        --user "${IOBROKER_USER}:${IOBROKER_PASSWORD}" \ 
 +        --get \ 
 +        --data-urlencode "value=${VALUE}" \ 
 +        "${IOBROKER_URL}/v1/state/${ID}" \ 
 +        >/dev/null 
 +}
  
  
-    ( +notify_iobroker() {
-        cd "$TEMP_DEST" || exit 1 +
-        sha256sum -c MagicMirror.tar.gz.sha256 +
-    ) || exit 7+
  
 +    local STATUS="$1"
 +    local MESSAGE="$2"
 +    local BACKUP_PATH="${3:-}"
  
-    echo "SHA-256: OK"+    set_iobroker_state "${STATE_BASE}.Message" "$MESSAGE" || return 1 
 +    set_iobroker_state "${STATE_BASE}.BackupPath" "$BACKUP_PATH" || return 1 
 +    set_iobroker_state "${STATE_BASE}.LastRun" "$(date -Iseconds)" || return 1
  
 +    # Status zuletzt setzen: dieser löst Telegram aus.
 +    set_iobroker_state "${STATE_BASE}.Status" "$STATUS"
 +}
  
-    mv "$TEMP_DEST" "$FINAL_DEST" || exit 8 
  
 +mkdir -p "$LOGDIR"
  
-    echo +STAMP="$(date '+%Y-%m-%d_%H-%M-%S')"
-    echo "==================================================" +
-    echo "BACKUP ERFOLGREICH" +
-    echo "Ende: $(date)" +
-    echo +
-    echo "Archiv:" +
-    echo "$FINAL_DEST/MagicMirror.tar.gz" +
-    echo +
-    echo "Prüfsumme:" +
-    echo "$FINAL_DEST/MagicMirror.tar.gz.sha256" +
-    echo +
-    echo "Größe:" +
-    du -h "$FINAL_DEST/MagicMirror.tar.gz" +
-    echo "=================================================="+
  
-    exit 0 +DEST="$AUTO_BASE/MagicMirror_Auto_$STAMP"
-fi+
  
 +LOG="$LOGDIR/MagicMirror_Auto_$STAMP.log"
  
-if [[ ! -d "$SOURCE" ]]; then 
  
-    echo "FEHLER: MagicMirror-Ordner wurde nicht gefunden:" +set_iobroker_state "${STATE_BASE}.Status" "running" || true
-    echo "$SOURCE"+
  
-    exit 1 
-fi 
  
 +"$BACKUP_SCRIPT" --worker "$DEST" >"$LOG" 2>&1
  
-echo "Prüfe NAS ..."+RESULT=$?
  
  
-if ! check_nas; then+if [[ $RESULT -eq 0 ]]; then
  
-    echo +    SIZE="$(du -h "$DEST/MagicMirror.tar.gz" | awk '{print $1}')"
-    echo "BACKUP NICHT GESTARTET" +
-    echo "Das NAS ist offline oder der Share nicht gemountet." +
-    echo "Es wurden KEINE Daten lokal nach /mnt/nasbackup geschrieben."+
  
-    exit 1 +    mapfile -t BACKUPS < <( 
-fi+        find "$AUTO_BASE" \ 
 +            -mindepth 1 \ 
 +            -maxdepth 1 \ 
 +            -type d \ 
 +            -name 'MagicMirror_Auto_*' \ 
 +            ! -name '*_INCOMPLETE' \ 
 +            -printf '%f\n' \ 
 +            | sort -r 
 +    )
  
 +    if (( ${#BACKUPS[@]} > KEEP_BACKUPS )); then
  
-mkdir -p "$BACKUP_BASE" +        for ((i=KEEP_BACKUPS; i<${#BACKUPS[@]}; i++)); do 
-mkdir -p "$LOGDIR"+            rm -rf -- "$AUTO_BASE/${BACKUPS[$i]}" 
 +        done
  
 +    fi
  
-STAMP="$(date '+%Y-%m-%d_%H-%M-%S')" 
  
-DEST="$BACKUP_BASE/MagicMirror_$STAMP"+    MESSAGE="Automatisches MagicMirror-Backup erfolgreich. Größe: ${SIZE}. Es werden ${KEEP_BACKUPS} automatische Backups aufbewahrt."
  
-LOG="$LOGDIR/MagicMirror_$STAMP.log"+    notify_iobroker "success" "$MESSAGE" "$DEST" || true
  
 +    exit 0
 +fi
  
-echo "NAS ist erreichbar." 
-echo 
-echo "Backup wird im Hintergrund gestartet." 
-echo "Quelle: $SOURCE" 
-echo "Ziel:   $DEST" 
-echo "Log:    $LOG" 
-echo 
  
 +MESSAGE="Automatisches MagicMirror-Backup fehlgeschlagen. Exit-Code: ${RESULT}. Log: ${LOG}"
  
-nohup "$0" --worker "$DEST" >"$LOG" 2>&1 < /dev/null &+notify_iobroker "error" "$MESSAGE" "${DEST}_INCOMPLETE" || true
  
-PID=$! +exit "$RESULT"
- +
- +
-echo "Backup-Prozess gestartet." +
-echo "PID: $PID" +
-echo +
-echo "Status ansehen mit:" +
-echo "tail -f \"$LOG\""+
 </code> </code>
  
- +Ausführbar machen:
-===== 3. Script ausführbar machen =====+
  
 <code bash> <code bash>
-chmod +x ~/bin/backup_magicmirror.sh+chmod +x ~/bin/backup_magicmirror_weekly.sh
 </code> </code>
  
- +Manueller Test:
-====== Backup verwenden ====== +
- +
-===== Backup starten =====+
  
 <code bash> <code bash>
-~/bin/backup_magicmirror.sh+~/bin/backup_magicmirror_weekly.sh
 </code> </code>
  
-Danach läuft die Sicherung im Hintergrund.+Bei Erfolg:
  
-Das Terminal bzw. die SSH-Verbindung kann geschlossen werden.+  * Backup liegt unter ''Automatische_Backups'' 
 +  * Telegram-Meldung wird gesendet 
 +  * Exit-Code ist ''0''
  
  
-===== Status ansehen =====+====== 6. systemd-Timer ======
  
-Neuestes Log:+===== Service =====
  
 <code bash> <code bash>
-tail -f "$(ls -t ~/magicmirror-backup-logs/*.log | head -1)"+sudo nano /etc/systemd/system/magicmirror-backup-weekly.service
 </code> </code>
  
-''Ctrl+C'' beendet nur die Loganzeige.+<code ini> 
 +[Unit] 
 +Description=Wöchentliches MagicMirror Backup auf NAS 
 +Wants=network-online.target 
 +After=network-online.target
  
-Das Backup läuft unabhängig davon weiter.+[Service] 
 +Type=oneshot 
 +User=<PI_USER> 
 +Group=<PI_USER> 
 +Environment=HOME=/home/<PI_USER> 
 +WorkingDirectory=/home/<PI_USER>
  
 +ExecStart=/home/<PI_USER>/bin/backup_magicmirror_weekly.sh
  
-===== Prüfen, ob ein Backup läuft ===== +TimeoutStartSec=infinity
- +
-<code bash> +
-pgrep -af 'backup_magicmirror|tar|gzip'+
 </code> </code>
  
-Keine Ausgabe bedeutet, dass aktuell kein Backup-Prozess läuft. 
  
 +===== Timer =====
  
-===== Erfolgreiches Backup =====+<code bash> 
 +sudo nano /etc/systemd/system/magicmirror-backup-weekly.timer 
 +</code>
  
-Im Log muss am Ende erscheinen:+<code ini> 
 +[Unit] 
 +Description=MagicMirror Backup jeden Sonntag um 01:00 Uhr
  
-<code> +[Timer] 
-gzip: OK +OnCalendar=Sun *-*-* 01:00:00 
-tar: OK +Persistent=true 
-MagicMirror.tar.gz: OK +AccuracySec=1min
-SHA-256: OK+
  
-BACKUP ERFOLGREICH+[Install] 
 +WantedBy=timers.target
 </code> </code>
  
-Ein fertiges Backup trägt keinen Zusatz ''_INCOMPLETE''. 
  
 +===== Aktivieren =====
  
-====== Backup überprüfen ======+<code bash> 
 +sudo systemctl daemon-reload 
 +sudo systemctl enable --now magicmirror-backup-weekly.timer 
 +</code>
  
-===== SHA-256 prüfen ===== +Kontrolle:
- +
-In das Backup-Verzeichnis wechseln:+
  
 <code bash> <code bash>
-cd /mnt/nasbackup/Manuelle_Backups/MagicMirror_YYYY-MM-DD_HH-MM-SS+systemctl list-timers --all | grep magicmirror
 </code> </code>
  
-Prüfen:+Timer-Status:
  
 <code bash> <code bash>
-sha256sum -c MagicMirror.tar.gz.sha256+systemctl status magicmirror-backup-weekly.timer --no-pager
 </code> </code>
  
Zeile 606: Zeile 632:
  
 <code> <code>
-MagicMirror.tar.gz: OK+Active: active (waiting)
 </code> </code>
  
  
-===== gzip prüfen =====+===== Service manuell testen =====
  
 <code bash> <code bash>
-gzip -t MagicMirror.tar.gz+sudo systemctl start magicmirror-backup-weekly.service
 </code> </code>
  
-Keine Ausgabe bedeutet Erfolg. +Danach:
- +
- +
-===== Inhalt des Archivs ansehen =====+
  
 <code bash> <code bash>
-tar -tzf MagicMirror.tar.gz | less+systemctl status magicmirror-backup-weekly.service --no-pager
 </code> </code>
  
  
-====== Archiv auf dem NAS entpacken ======+====== 7. Backups prüfen ======
  
-Falls das Archiv lediglich angesehen werden soll, kann es in einen separaten Ordner entpackt werden. +===== SHA-256 =====
- +
-Beispiel:+
  
 <code bash> <code bash>
-mkdir MagicMirror_ENTPACKT +cd /mnt/nasbackup/Manuelle_Backups/MagicMirror_YYYY-MM-DD_HH-MM-SS 
- +sha256sum -c MagicMirror.tar.gz.sha256
-tar -xzf MagicMirror.tar.gz -C MagicMirror_ENTPACKT+
 </code> </code>
  
-Da Symlinks beim Backup dereferenziert werden und ''node_modules'' nicht enthalten sind, besteht das Archiv überwiegend aus normalen Dateien und Verzeichnissen.+Erwartet:
  
 +<code>
 +MagicMirror.tar.gz: OK
 +</code>
  
-====== Wiederherstellung auf einem neuen Raspberry Pi ====== 
  
-===== 1. Grundsystem installieren =====+===== Archivinhalt ansehen =====
  
-Auf dem neuen Raspberry Pi zuerst:+<code bash> 
 +tar -tzf MagicMirror.tar.gz | less 
 +</code>
  
-  * Raspberry Pi OS installieren 
-  * Benutzer einrichten 
-  * Netzwerk konfigurieren 
-  * NAS-Mount nach dieser Anleitung einrichten 
-  * passende Node.js-Version installieren 
-  * MagicMirror-Grundvoraussetzungen installieren 
  
 +====== 8. Wiederherstellung ======
  
-===== 2. Backup prüfen =====+===== Auf gleichem System =====
  
-<code bash> +Archiv prüfen:
-cd /mnt/nasbackup/Manuelle_Backups/MagicMirror_YYYY-MM-DD_HH-MM-SS+
  
 +<code bash>
 sha256sum -c MagicMirror.tar.gz.sha256 sha256sum -c MagicMirror.tar.gz.sha256
 </code> </code>
  
-Nur bei:+Dann:
  
-<code> +<code bash> 
-MagicMirror.tar.gz: OK+tar -xzf MagicMirror.tar.gz -C ~
 </code> </code>
  
-weiterarbeiten. 
  
 +===== Auf einem neuen Raspberry Pi =====
  
-===== 3. Vorhandenen MagicMirror-Ordner sichern =====+Bei einem neuen Pi sollte MagicMirror und Node.js zunächst frisch installiert werden.
  
-Falls bereits ein Ordner existiert:+Aus dem Backup werden anschließend insbesondere übernommen:
  
-<code bash> +  * ''config/config.js'' 
-mv ~/MagicMirror ~/MagicMirror_alt +  * ''css/custom.css'' 
-</code>+  * Drittmodule und deren Konfiguration 
 +  * eigene Bilder, Skripte und Dateien
  
 +''node_modules'' werden bewusst nicht wiederhergestellt.
  
-===== 4. Backup wiederherstellen =====+Die Abhängigkeiten werden auf dem neuen System neu installiert.
  
-<code bash> 
-tar -xzf /mnt/nasbackup/Manuelle_Backups/MagicMirror_YYYY-MM-DD_HH-MM-SS/MagicMirror.tar.gz -C ~ 
-</code> 
  
-Danach existiert wieder:+====== 9. Alltag ======
  
-<code> +===== Manuelles Backup starten ===== 
-~/MagicMirror+ 
 +<code bash> 
 +~/bin/backup_magicmirror.sh
 </code> </code>
  
 +Bei Erfolg oder Fehler wird automatisch eine Telegram-Nachricht über ioBroker gesendet.
  
-===== 5. Node.js-Abhängigkeiten neu installieren ===== 
  
-''node_modules'' befinden sich absichtlich nicht im Backup.+===== Aktuelles Backup-Log =====
  
-Deshalb müssen die Abhängigkeiten passend zur neuen Umgebung neu installiert werden.+<code bash> 
 +tail -f "$(ls -t ~/magicmirror-backup-logs/*.log | head -1)" 
 +</code>
  
-Für den MagicMirror-Hauptordner und installierte Drittmodule ist die jeweils aktuelle Installationsanleitung zu verwenden. 
  
-Das ist insbesondere bei einem Wechsel auf einen neuen Pi oder eine neue Node.js-/MagicMirror-Version wichtig.+===== Automatisches Backup =====
  
 +Das automatische Backup läuft:
  
-====== Verhalten bei nicht erreichbarem NAS ====== +<code> 
- +jeden Sonntag um 01:00 Uhr 
-Das Script prüft vor dem Start: +</code>
- +
-  * ob der Mountpunkt erreichbar ist +
-  * ob dort tatsächlich CIFS verwendet wird +
-  * ob genau der konfigurierte NAS-Share gemountet ist+
  
-Ist das NAS offline, wird das Backup nicht gestartet. +Es werden maximal:
- +
-Dadurch kann nicht versehentlich auf die lokale SSD unter+
  
 <code> <code>
-/mnt/nasbackup+4 automatische Backups
 </code> </code>
  
-geschrieben werden.+aufbewahrt.
  
 +Manuelle Backups werden dadurch nicht gelöscht.
  
-====== Wichtige Dateien ====== 
  
-^ Pfad ^ Funktion ^ +===== Timer prüfen =====
-| ''~/MagicMirror'' | zu sichernder MagicMirror-Ordner | +
-| ''~/bin/backup_magicmirror.sh'' | Backup-Script | +
-| ''~/magicmirror-backup-logs'' | Backup-Logs | +
-| ''/mnt/nasbackup'' | NAS-Mountpunkt | +
-| ''/mnt/nasbackup/Manuelle_Backups'' | Backup-Ziel | +
-| ''/etc/samba/credentials-nasbackup'' | NAS-Zugangsdaten | +
-| ''/etc/fstab'' | NAS-Automount-Konfiguration |+
  
 +<code bash>
 +systemctl list-timers --all | grep magicmirror
 +</code>
  
-====== Kurzfassung ====== 
  
-Backup starten:+===== NAS prüfen =====
  
 <code bash> <code bash>
-~/bin/backup_magicmirror.sh+findmnt /mnt/nasbackup 
 +df -h /mnt/nasbackup
 </code> </code>
  
-Status ansehen: 
  
-<code bash> +===== Backup prüfen =====
-tail -f "$(ls -t ~/magicmirror-backup-logs/*.log | head -1)" +
-</code>+
  
-Backup prüfen:+Im jeweiligen Backup-Verzeichnis:
  
 <code bash> <code bash>
-cd /mnt/nasbackup/Manuelle_Backups/MagicMirror_YYYY-MM-DD_HH-MM-SS 
- 
 sha256sum -c MagicMirror.tar.gz.sha256 sha256sum -c MagicMirror.tar.gz.sha256
 </code> </code>
  
-Ein Backup gilt als gültig, wenn:+Erwartet:
  
-  * im Log ''BACKUP ERFOLGREICH'' steht +<code> 
-  * der Ordner keinen Zusatz ''_INCOMPLETE'' besitzt +MagicMirror.tar.gz: OK 
-  * die SHA-256-Prüfung ''OK'' meldet+</code>