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: Datenbanksicherung – Datenbanksicherung mit E-Mail Benachrichtigung – FTP-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?
- Ich wollte CronJobs sparen, also Datenbank- und FTP-Backup in einem Script ausführen und
- eine E-Mail Benachrichtigung mit Downloadlink auch von der FTP-Sicherung aber
- trotzdem eine tägliche Datenbanksicherung, komplette FTP-Sicherungen nur an bestimmten Tagen und
- 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öscht.<br>"; } else { echo "Die Datei " .$file . " wurde <b>nicht</b> gelö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üssen zunä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ü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ü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ä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öscht.<br>"; } else { echo "Die Datei " .$file . " wurde <b>nicht</b> gelö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üssen zunä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ü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ü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ä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.