Datenbank- und Webseitenbackup mit E-Mail Benachrichtigung und Downloadlink bei All-Inkl.com

Die regelmäßige Sicherung des Webspaces ist zwar nicht zwingend aber durchaus sehr zu empfehlen. Nur mit einer Sicherung kann bei einem Server-Crash oder einem Hackerangriff die Webseite wieder hergestellt werden. Mein Hosting-Anbieter All-Inkl.com bietet für diese Zwecke schon vorgefertigte Scripte an: DatenbanksicherungDatenbanksicherung mit E-Mail BenachrichtigungFTP-Sicherung des Webspaces. WordPress-Benutzer werden auf diese Scripte nicht angewiesen sein – für WordPress gibt es ohnehin genug Backup-Plugins.

Für alle, die auch diverse andere CMS oder irgendwelche Software auf ihrem Server bei All-Inkl hosten, habe ich eine etwas erweiterte Lösung dieser Scripte zur Hand.

Warum überhaupt ein erweitertes Script bzw. was habe ich angepasst?

  1. Ich wollte CronJobs sparen, also Datenbank- und FTP-Backup in einem Script ausführen und
  2. eine E-Mail Benachrichtigung mit Downloadlink auch von der FTP-Sicherung aber
  3. trotzdem eine tägliche Datenbanksicherung, komplette FTP-Sicherungen nur an bestimmten Tagen und
  4. alte Backups automatisch vom All-Inkl Server löschen um nicht sinnlos Speicherplatz zu vergeuden.

Das alles gilt es jetzt in einem Script zu vereinen. Dazu erfinden wir das Rad nicht neu sondern passen die bereits vorhandenen Scripte etwas an und erweitern sie lediglich um ein paar extra Zeilen Code. Als erstes beginnen wir gleich mal mit den Einstellungen des Originalscriptes der Datenbanksicherung inkl. E-Mail Benachrichtigung. Die Angaben müssen logischerweise an ihre Bedürfnisse angepasst werden.

######### EINSTELLUNGEN ##########

# Datenbankname
    $db_name = "d0000000";

# Datenbankpasswort
    $db_passwd = "xxxxxxxxxxxx";

# Mögliche Auswahl:  yes  |  ja  |  1
    $downloadlink_erstellen = "ja";
    $bestaetigungsmail_senden = "ja";
    $bestaetigungsmail_adresse = "ihre@email-adresse.com";
    $bestaetigungsmail_betreff = "[BACKUP] " . $_SERVER['HTTP_HOST'];

# Anzahl der Tage nachdem alte Backups automatisch gelöscht werden
    $deltag = "7"; // SQL und FTP Dateien älter als Tag X werden gelöscht

# Zu sicherndes Unterverzeichnis. Bleibt leer, wenn gesamter Account gesichert werden soll.
//    $verzeichnis = ""; // kompletter Account
    $verzeichnis = "/hauptverzeichnis/unterverzeichnis/"; // zu sicherndes Unterverzeichnis

# Auszuschließende Ressourcen des FTP Backups
    $ignorieren = array("*.tar.gz", "usage", "logs"); // FTP-Backup mit Datenbanksicherung
//    $ignorieren = array("*.sql.gz", "*.tar.gz", "usage", "logs"); // FTP-Backup ohne Datenbanksicherung
//    $ignorieren = array("*.tar.gz", "usage", "logs", "wp-content/plugins" ); // FTP-Backup mit Datenbanksicherung, ohne WordPress Plugins

# FTP Backup nur an folgenden Tagen (Angabe Zweistellig mit führender Null)
    $ftptag = array(
        "07", // [0]
        "14", // [1]
        "21", // [2]
        "28"  // [3]
    );

# Beginn der Nachricht
    $message = "<b>Backup von " . $_SERVER['HTTP_HOST'] . "</b><br><br>";

Ich denke, dass dieser Code schon selbsterklärend ist, aber kurz noch im Schnelldurchlauf. Die Angaben zu ihrer Datenbank angeben, ihre E-Mail Adresse hinzufügen, die Tage der automatischen Löschung angeben, das zu sichernde Verzeichnis festlegen und die auszuschließenden Dateiendungen oder Verzeichnisse. Die FTP Backups werden in diesem Beispiel jeweils am 7., 14., 21. und 28. des jeweiligen Monats erstellt, WENN DAS SCRIPT AUCH AN DIESEN TAGEN AUSGEFÜHRT WIRD!

Dazu einen CronJob benutzen – bei der Einstellung „Täglich“ wird täglich dabei die Datenbank gesichert, aber nur an den festgelegten FTP-Backup-Tagen auch zusätzlich noch dieses erstellt. Sollten sie zB nur einmal im Monat ein FTP-Backup wünschen, müssen sie nicht unbedingt das Script umschreiben – sie können auch vier mal den gleichen Tag eingeben (zB 4x „07“).

Da ich mehrere Domains bei All-Inkl hoste verwende ich $_SERVER['HTTP_HOST'] um automatisch statt eines festgelegten Wertes den jeweiligen Domainnamen hinzuzufügen. Somit weis ich auch sofort, für welche Domain dieses Backup erstellt wurde.

######### Löschvorgang ##########

# Anzahl der Tage prüfen
    if ( $deltag == "" ) {
        $deltag = "1";
    }
    $delete = time()-( 60*60*24*$deltag );

# Alte FTP und SQL Dateien löschen
    foreach( glob("*.gz") as $file ) {
        $erstellt = filemtime( $file );
        if( $erstellt <= $delete ) {
            if ( unlink( $file ) ) {
                $message .= "Die Datei " . $file . " wurde erfolgreich gel&ouml;scht.<br>";
            } else {
                echo "Die Datei " .$file . " wurde <b>nicht</b> gel&ouml;scht.<br>";
            }
        }
    }

Als nächstes habe ich den Löschvorgang hinzugefügt. Alle FTP- und Datenbanksicherung die älter als die festgelegten Tage sind werden gelöscht. Mit der Dateiendung .gz stellen wir sicher, dass wir uns nicht auch das Script selber löschen.

Dann fügen wir den Code für das Datenbankbackup hinzu. Dieser Codeteil ist zum größten Teil direkt vom originalen Script. Hierbei wird das Format des Dateinamens festgelegt, das Backup der Datenbank ausgelesen und gespeichert, die Größe der Datei ermittelt und abschließend zur Nachricht hinzugefügt zwecks späterer Ausgabe bzw. Mailversand.

######### Datenbankbackup ##########

# Datenbank Namensformat
    $sql_file = $_SERVER['HTTP_HOST'] . "_" . $db_name . "_" . date('_Y-m-d_His') . ".sql";

# Daten überprüfen
    if ( $db_name == "IhreDatenBank" or $db_passwd == "IhrDatenBankPasswort" ) {
        die("FEHLER: Sie m&uuml;ssen zun&auml;chst Ihre Datenbankdaten im Script eingeben!");
    }
    
    if ( file_exists($sql_file) or file_exists($sql_file . ".gz") ) {
        die("FEHLER: Das zu erstellende Dump existiert bereits!");
    }

# dump erstellen
    exec("mysqldump -u $db_name -p'$db_passwd' --quick --allow-keywords --add-drop-table --complete-insert --quote-names $db_name >$sql_file");
    exec("gzip $sql_file");

# Größe ermitteln
    $datei = $sql_file . ".gz";
    $size = filesize($datei);
    $i = 0;
    while ( $size > 1024 ) {
        $i++;
        $size = $size / 1024;
    }

    $fileSizeNames = array(" Bytes", " KiloBytes", " MegaBytes", " GigaBytes", " TerraBytes");
    $size = round($size,2);
    $size = str_replace(".", ",", $size);
    $groesse = "$size $fileSizeNames[$i]";

# Nachricht erstellen
    $message .= "Ihr Backup der Datenbank <b>" . $db_name . "</b> wurde durchgef&uuml;hrt.<br>";

# Downloadlink erstellen
    if ($downloadlink_erstellen == "yes" or $downloadlink_erstellen == "ja" or $downloadlink_erstellen == "1") {
        $link = 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF'];
        $link = str_replace(basename(__FILE__),$datei,$link);
        $message .= "<b>Datenbankbackup</b> (" . $groesse . "): <a href=" . $link . ">" . $datei . "</a><br>";
    }

Dann widmen wir uns dem FTP-Backup. Dabei fragen wir den aktuellen Tag ab und vergleichen ihn mit unseren Einstellungen. Ist die Anforderung gegeben, dann wird ein Backup erstellt, dabei ebenfalls die Dateigröße ermittelt und zur Nachricht hinzugefügt – inkl. Downloadlink, damit wir das Backup auch ganz bequem nach erhalten des E-Mails herunterladen können.

######### FTP-Backup ##########

# aktuellen Tag auslesen und prüfen
    $ftptime = date( 'd' );
    if ( ( $ftptag[0] == $ftptime ) || ( $ftptag[1] == $ftptime ) || ( $ftptag[2] == $ftptime ) || ( $ftptag[3] == $ftptime ) ) {
    
    # PHP-Konfiguration optimieren
        @error_reporting(E_ALL ^ E_WARNING);
        @ini_set("max_execution_time", 300);
        @ini_set("memory_limit", "256M");

    # PEAR-Klasse einbinden und Archiv erstellen
        $pfad = preg_replace('/(/www/htdocs/w+/).*/', '$1', realpath(__FILE__));
        include "Archive/Tar.php";

    # FTP Namesformat
        $archivname = $_SERVER['HTTP_HOST'].date('_Y-m-d_His').".tar.gz";
        
        $archiv = new Archive_Tar($archivname, true);
        $archiv->setIgnoreList($ignorieren);
        $archiv->createModify($pfad.$verzeichnis, "", $pfad);

    # FTP Größe ermitteln
        $datei = $archivname;
        $size = filesize($datei);
        $i = 0;
        while ( $size > 1024 ) {
            $i++;
            $size = $size / 1024;
        }
        
        $fileSizeNames = array(" Bytes", " KiloBytes", " MegaBytes", " GigaBytes", " TerraBytes");
        $size = round($size,2);
        $size = str_replace(".", ",", $size);
        $groesse = "$size $fileSizeNames[$i]";

    # Downloadlink erstellen
        if ($downloadlink_erstellen == "yes" or $downloadlink_erstellen == "ja" or $downloadlink_erstellen == "1") {
            $ftplink = 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF'];
            $ftplink = str_replace(basename(__FILE__),$archivname,$ftplink);
            $message .= "<b>FTP und Datenbankbackup</b> (" . $groesse . "): <a href='" . $ftplink . "'>" . $archivname . "</a>";
        }

    } // ftptag ende

Als nächstes können wir uns noch bei manuellem Aufruf des Scriptes die dementsprechende Nachricht am Bildschirm anzeigen lassen. Mit // können wir diese deaktivieren, falls wir sie nicht brauchen.

######### Meldung am Bildschirm ausgeben ##########

# Meldung aktiv
    echo $message;

# Meldung inaktiv
//    echo $message;

Zu krönenden Abschluß möchten wir natürlich noch eine E-Mail erhalten, in der wir einiges an Informationen bekommen.

  • Anzeige für welche Domain diese(s) Backup(s) erstellt wurde(n)
  • Anzeige der alten Backups die gelöscht wurden
  • Dateinamen, Dateigröße und Downloadlink von der Datenbanksicherung
  • Dateinamen, Dateigröße und Downloadlink von der FTP-Sicherung

E-Mail-Versand und Downloadlink Erstellung müssen hierfür natürlich aktiviert sein!

######### E-Mail versenden ##########

    # Prüfen ob Bestätigungsmail aktiviert ist
    if ($bestaetigungsmail_senden == "yes" or $bestaetigungsmail_senden == "ja" or $bestaetigungsmail_senden == "1") {
        # E-Mail-Adresse prüfen
        if(!preg_match( '/^([a-zA-Z0-9])+([.a-zA-Z0-9_-])*@([a-zA-Z0-9_-])+(.[a-zA-Z0-9_-]+)+/' , $bestaetigungsmail_adresse)) {
            echo "<br>FEHLER: Mail konnte nicht versendet werden, da die Adresse ung&uuml;ltig ist!";
        } else { // senden
            mail(
                $bestaetigungsmail_adresse,
                $bestaetigungsmail_betreff,
                $message,
                "From: backupscript@{$_SERVER['SERVER_NAME']}rn" . "Reply-To: backupscript@{$_SERVER['SERVER_NAME']}rn" . "Content-Type: text/htmlrn"
            ) or die("FEHLER: Mail konnte wegen eines unbekannten Fehlers nicht versendet werden");
            echo "<br>Best&auml;tigungsmail wurde erfolgreich versandt!";
        }
    }

Dieses Script einfach in einer Datei abspeichern zB backup.php oder backup.phpx – Das ist Abhängig davon, welches Hostingpaket sie haben (mehr Infos dazu direkt bei den Links der Originalscripte von All-Inkl am Beitragsanfang). Diese Datei dann wie auch von All-Inkl angegeben in den Ordner backup der Domain kopieren, welchen sie ebenfalls zuerst vorher erstellen müssen. Im KAS-Center von All-Inkl können sie dann unter Tools einen CronJob anlegen und zB täglich ausführen lassen. Nur beim Privat-Tarif sind derzeit noch keine CronJobs inkludiert. In einem solchen Fall entweder wieder Handarbeit oder einen kleinen Aufpreis in Kauf nehmen.

Der Vollständigkeit halber noch einmal das komplette Script:

<?php
/* Backupscript für All-Inkl
*
*
* Basierend auf den originalen Scripten von All-Inkl
* http://all-inkl.com/wichtig/anleitungen/datensicherung/mysql/php-skript-zum-sichern-und-wiederherstellen-einer-datenbank/dump-erstellen-mit-e-mail-benachrichtigung_85.html
* http://all-inkl.com/wichtig/anleitungen/datensicherung/webspace/php-skript-zum-sichern-der-ftp-daten/einrichten_97.html
*
* Erweitert von Zöchbauer Manfred | https://zoechbauer.name
*/


######### EINSTELLUNGEN ##########

# Datenbankname
    $db_name = "d0000000";

# Datenbankpasswort
    $db_passwd = "xxxxxxxxxxxx";

# Mögliche Auswahl:  yes  |  ja  |  1
    $downloadlink_erstellen = "ja";
    $bestaetigungsmail_senden = "ja";
    $bestaetigungsmail_adresse = "ihre@email-adresse.com";
    $bestaetigungsmail_betreff = "[BACKUP] " . $_SERVER['HTTP_HOST'];

# Anzahl der Tage nachdem alte Backups automatisch gelöscht werden
    $deltag = "7"; // SQL und FTP Dateien älter als Tag X werden gelöscht

# Zu sicherndes Unterverzeichnis. Bleibt leer, wenn gesamter Account gesichert werden soll.
//    $verzeichnis = ""; // kompletter Account
    $verzeichnis = "/hauptverzeichnis/unterverzeichnis/"; // zu sicherndes Unterverzeichnis

# Auszuschließende Ressourcen des FTP Backups
    $ignorieren = array("*.tar.gz", "usage", "logs"); // FTP-Backup mit Datenbanksicherung
//    $ignorieren = array("*.sql.gz", "*.tar.gz", "usage", "logs"); // FTP-Backup ohne Datenbanksicherung
//    $ignorieren = array("*.tar.gz", "usage", "logs", "wp-content/plugins" ); // FTP-Backup mit Datenbanksicherung, ohne WordPress Plugins

# FTP Backup nur an folgenden Tagen (Angabe Zweistellig mit führender Null)
    $ftptag = array(
        "07", // [0]
        "14", // [1]
        "21", // [2]
        "28"  // [3]
    );

# Beginn der Nachricht
    $message = "<b>Backup von " . $_SERVER['HTTP_HOST'] . "</b><br><br>";




###############################################################################################
######### AB HIER BITTE NICHTS MEHR ÄNDERN!!! -> Ausser sie wissen genau was sie tun ##########
###############################################################################################



######### Löschvorgang ##########

# Anzahl der Tage prüfen
    if ( $deltag == "" ) {
        $deltag = "1";
    }
    $delete = time()-( 60*60*24*$deltag );

# Alte FTP und SQL Dateien löschen
    foreach( glob("*.gz") as $file ) {
        $erstellt = filemtime( $file );
        if( $erstellt <= $delete ) {
            if ( unlink( $file ) ) {
                $message .= "Die Datei " . $file . " wurde erfolgreich gel&ouml;scht.<br>";
            } else {
                echo "Die Datei " .$file . " wurde <b>nicht</b> gel&ouml;scht.<br>";
            }
        }
    }



######### Datenbankbackup ##########

# Datenbank Namensformat
    $sql_file = $_SERVER['HTTP_HOST'] . "_" . $db_name . "_" . date('_Y-m-d_His') . ".sql";

# Daten überprüfen
    if ( $db_name == "IhreDatenBank" or $db_passwd == "IhrDatenBankPasswort" ) {
        die("FEHLER: Sie m&uuml;ssen zun&auml;chst Ihre Datenbankdaten im Script eingeben!");
    }
    
    if ( file_exists($sql_file) or file_exists($sql_file . ".gz") ) {
        die("FEHLER: Das zu erstellende Dump existiert bereits!");
    }

# dump erstellen
    exec("mysqldump -u $db_name -p'$db_passwd' --quick --allow-keywords --add-drop-table --complete-insert --quote-names $db_name >$sql_file");
    exec("gzip $sql_file");

# Größe ermitteln
    $datei = $sql_file . ".gz";
    $size = filesize($datei);
    $i = 0;
    while ( $size > 1024 ) {
        $i++;
        $size = $size / 1024;
    }

    $fileSizeNames = array(" Bytes", " KiloBytes", " MegaBytes", " GigaBytes", " TerraBytes");
    $size = round($size,2);
    $size = str_replace(".", ",", $size);
    $groesse = "$size $fileSizeNames[$i]";

# Nachricht erstellen
    $message .= "Ihr Backup der Datenbank <b>" . $db_name . "</b> wurde durchgef&uuml;hrt.<br>";

# Downloadlink erstellen
    if ($downloadlink_erstellen == "yes" or $downloadlink_erstellen == "ja" or $downloadlink_erstellen == "1") {
        $link = 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF'];
        $link = str_replace(basename(__FILE__),$datei,$link);
        $message .= "<b>Datenbankbackup</b> (" . $groesse . "): <a href=" . $link . ">" . $datei . "</a><br>";
    }



######### FTP-Backup ##########

# aktuellen Tag auslesen und prüfen
    $ftptime = date( 'd' );
    if ( ( $ftptag[0] == $ftptime ) || ( $ftptag[1] == $ftptime ) || ( $ftptag[2] == $ftptime ) || ( $ftptag[3] == $ftptime ) ) {
    
    # PHP-Konfiguration optimieren
        @error_reporting(E_ALL ^ E_WARNING);
        @ini_set("max_execution_time", 300);
        @ini_set("memory_limit", "256M");

    # PEAR-Klasse einbinden und Archiv erstellen
        $pfad = preg_replace('/(/www/htdocs/w+/).*/', '$1', realpath(__FILE__));
        include "Archive/Tar.php";

    # FTP Namesformat
        $archivname = $_SERVER['HTTP_HOST'].date('_Y-m-d_His').".tar.gz";
        
        $archiv = new Archive_Tar($archivname, true);
        $archiv->setIgnoreList($ignorieren);
        $archiv->createModify($pfad.$verzeichnis, "", $pfad);

    # FTP Größe ermitteln
        $datei = $archivname;
        $size = filesize($datei);
        $i = 0;
        while ( $size > 1024 ) {
            $i++;
            $size = $size / 1024;
        }
        
        $fileSizeNames = array(" Bytes", " KiloBytes", " MegaBytes", " GigaBytes", " TerraBytes");
        $size = round($size,2);
        $size = str_replace(".", ",", $size);
        $groesse = "$size $fileSizeNames[$i]";

    # Downloadlink erstellen
        if ($downloadlink_erstellen == "yes" or $downloadlink_erstellen == "ja" or $downloadlink_erstellen == "1") {
            $ftplink = 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF'];
            $ftplink = str_replace(basename(__FILE__),$archivname,$ftplink);
            $message .= "<b>FTP und Datenbankbackup</b> (" . $groesse . "): <a href='" . $ftplink . "'>" . $archivname . "</a>";
        }

    } // ftptag ende



######### Meldung am Bildschirm ausgeben ##########

# Meldung aktiv
    echo $message;



######### E-Mail versenden ##########

    # Prüfen ob Bestätigungsmail aktiviert ist
    if ($bestaetigungsmail_senden == "yes" or $bestaetigungsmail_senden == "ja" or $bestaetigungsmail_senden == "1") {
        # E-Mail-Adresse prüfen
        if(!preg_match( '/^([a-zA-Z0-9])+([.a-zA-Z0-9_-])*@([a-zA-Z0-9_-])+(.[a-zA-Z0-9_-]+)+/' , $bestaetigungsmail_adresse)) {
            echo "<br>FEHLER: Mail konnte nicht versendet werden, da die Adresse ung&uuml;ltig ist!";
        } else { // senden
            mail(
                $bestaetigungsmail_adresse,
                $bestaetigungsmail_betreff,
                $message,
                "From: backupscript@{$_SERVER['SERVER_NAME']}rn" . "Reply-To: backupscript@{$_SERVER['SERVER_NAME']}rn" . "Content-Type: text/htmlrn"
            ) or die("FEHLER: Mail konnte wegen eines unbekannten Fehlers nicht versendet werden");
            echo "<br>Best&auml;tigungsmail wurde erfolgreich versandt!";
        }
    }
?>

Dieses Script leistet mir sehr gute Dienste und verwende es mittlerweile bei all meinen Domains auf All-Inkl. Ich übernehme aber auf keinen Fall irgendwelche Haftungen für eventuelle Datenverluste, was auch immer – oder wie man so schön sagt: Benutzung auf eigene Gefahr! und bis PHP 5.6 getestet!




Bitte beachten Sie, dass dieser Beitrag bereits vor über einem Jahr geschrieben wurde und unter umständen nicht mehr aktuell ist.