Du bist nicht angemeldet. Der Zugriff auf einige Boards wurde daher deaktiviert.
Seiten: 1
#1 18. Januar 2011 18:04
- Andiministrator
- Kabeljungwerker

- Ort: Plauen / Vogtland
- Registriert: 09. November 2010
- Beiträge: 264
- Webseite
Automatisiertes Backup - ein Ansatz
Das Backups wichtig sind, brauche ich Euch ja nicht zu erzählen. Bei einer steigenden Anzahl von Kunden steht man irgendwann vor dem Problem, dass regelmäßige Backups viel Zeit in Anspruch nehmen. Die Lösung des Problems besteht in der Automatisierung. Hier möchte ich Euch einmal meinen (selbstgestrickten) Ansatz für ein automatisiertes Backup vorstellen.
Meine Anforderungen:
Automatisiertes Backup von MySQL-Datenbank und wichtigen Verzeichnissen bzw. Dateien.
Möglichst kurze Ausführungszeit (bzw. geringe Serverbelastung)
Manuelle Auswahl-Möglichkeit für zu sichernde Dateien und Verzeichnisse
Automatisierter Transfer der verschiedenen Backups zu meinem Entwicklungsrechner (wo sie dann in meinen normalen Backup-Prozess eingebunden werden können)
Pack-Algorithmus vor dem Transfer der Dateien, um die Zeit der Dateiübertragung kurz zu halten
Voraussetzung dieser Lösung ist, dass Euer Webserver (bzw. PHP-Interpreter) das Ausführen des PHP-Kommandos "exec" ermöglicht. Außerdem solltet Ihr für die Automatisierung Cronjobs erstellen können.
1. Schritt
Als erstes muss ein Verzeichnis existieren, wo die Backups gespeichert werden können (z.B. /home/backups). Dieses Verzeichnis muss für den Cronjob beschreibbar sein.
2. Schritt
Nun wird auf dem Webserver das folgende PHP-Script gespeichert, bei mir heißt es "backup.php". Wichtig ist, dass es nicht von außen erreichbar ist (indem es z.B. durch eine .htaccess geschützt ist).
<?php
// initial stuff
$email_address = 'eure@mail-adresse.de'; # Wohin sollen die Erfolgs-/Fehlermeldungen geschickt werden?
$send_email = true; # Soll nach jedem Backup eine Mail versandt werden? true/false
$site_title = 'CMSms Backup eure-webseite.de'; # Was soll im Betreff der Mail stehen?
$path = '/home/www/'; # Wo liegt das CMS bzw. die Webseiten?
$backups = '/home/backups/'; # In welchem Verzeichnis sollen die Backups gespeichert werden? Achtung! Dieses Verzeichnis muss für dieses Script (bzw. den Cronjob) beschreibbar sein!
// set user directories and files to backup
$files = array(); // dont remove this line!
#$files[] = "verzeichnis oder datei";
$files[] = 'admin';
$files[] = 'css';
$files[] = 'doc';
$files[] = 'images';
$files[] = 'js';
$files[] = 'lib';
$files[] = 'modules';
$files[] = 'php';
$files[] = 'plugins';
$files[] = 'tmp';
$files[] = 'uploads';
$files[] = '.htaccess';
$files[] = 'config.php';
$files[] = 'favicon_cms.ico';
$files[] = 'favicon.ico';
$files[] = 'fileloc.php';
$files[] = 'include.php';
$files[] = 'index.php';
$files[] = 'moduleinterface.php';
$files[] = 'preview.php';
$files[] = 'robots.txt';
$files[] = 'sitemap.xml';
$files[] = 'soap.php';
$files[] = 'stylesheet.css';
$files[] = 'stylesheet.php';
$files[] = 'version.php';
/////////////////////////////////////////////////////////////////////
// --------- dont remove anything of the following lines --------- //
/////////////////////////////////////////////////////////////////////
// DB settings
$config = array();
include($path.'config.php');
$c_db['hostname'] = $config['db_hostname'];
$c_db['database'] = $config['db_name'];
$c_db['username'] = $config['db_username'];
$c_db['password'] = $config['db_password'];
// include version.php for getting out the CMSms version
include($path.'version.php');
// set return value array
$ra = array();
$ra['error'] = '';
$ra['message'] = '';
// clear backup directories
if (is_dir($backups.'mysql')) exec('/bin/rm -rf '.$backups.'mysql');
if (is_dir($backups.'files')) exec('/bin/rm -rf '.$backups.'files');
// create directories
if (!is_dir($backups)) mkdir($backups, 0700);
mkdir($backups.'mysql', 0700);
mkdir($backups.'files', 0700);
// create database dump
$sql_file = $backups.'mysql/dump_'.$c_db['database'].'_'.date('Ymd_Hi').'.sql';
exec('/usr/bin/mysqldump -h 127.0.0.1 --user='.$c_db['username'].' --password='.$c_db['password'].' --port=3307 --quick --allow-keywords --add-drop-table --complete-insert --quote-names '.$c_db['database'].' >'.$sql_file);
// get filesize of sql dump
$ra['sql_filesize'] = getFilesize($sql_file);
if ($ra['sql_filesize']<=0) { $ra['error'].= '<p>Problem with backup of the database or database is empty...</p>'; }
else {
$ra['message'].= '<p>Backup of database <strong>'.$c_db['database'].'</strong> was <span color="#00CCC0000">successful</span>.<br />';
$ra['message'].= 'Size of the dump file is <strong>'.$ra['sql_filesize'].'</strong>.</p>';
}
// backup file structure
$rootfiles = array();
$ra['backup_dirs'] = 0;
$ra['backup_files'] = 0;
foreach ($files as $f) {
if (is_dir($path.$f)) { exec('/bin/tar -zcvf '.$backups.'files/'.$f.'.tar.gz '.$path.$f); $ra['backup_dirs']++; }
else if (is_file($path.$f)) { $rootfiles[] = $f; }
}
if ($rootfiles) {
$str_rootfiles = '';
foreach ($rootfiles as $f) {
$str_rootfiles.= ' '.$path.$f;
$ra['backup_files']++;
}
exec('/bin/tar -zcvf '.$backups.'files/root_files.tar.gz'.$str_rootfiles);
}
if ($ra['backup_dirs']<=0 || $ra['backup_files']<=0) { $ra['error'].= '<p>Problem with backup of the file structure (quota limit?) or no files('.$ra['backup_files'].')/directories('.$ra['backup_dirs'].') are available...</p>'; }
else { $ra['message'].= '<p>Your file structure backup of <strong>'.$ra['backup_dirs'].' directories and '.$ra['backup_files'].' files</strong> was <span color="#00CCC0000">successful</span>.</p>'; }
// backup the whole system
$ra['backup_file'] = $backups.'backup_'.date('Ymd_Hi').'.tar.gz';
exec('/bin/tar -zcvf '.$ra['backup_file'].' '.$backups.'mysql '.$backups.'files');
$ra['backup_filesize'] = getFilesize($ra['backup_file']);
chmod ($ra['backup_file'], 0700);
if (!$ra['error']) {
$ra['message'].= '<p>System backup was successful.<br />';
$ra['message'].= 'Backup size of <strong>'.$ra['backup_file'].'</strong> is <strong>'.$ra['backup_filesize'].'</strong>.</p>';
}
// clear backup directories
exec('/bin/rm -rf '.$backups.'mysql');
exec('/bin/rm -rf '.$backups.'files');
// build message
$message = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="de" lang="de"><head>
<title>'.$site_title.'</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>';
$message.= '<p>Version of CMS made simple: '.$CMS_VERSION.'</p>';
if ($ra['error']) { $message.= '<p color="#CC0000"><strong>Errors</strong>:</p>'.$ra['error']; }
else { $message.= $ra['message']; }
$message.= '</body></html>';
// send email
if ($send_email) {
if(!preg_match( '/^([a-zA-Z0-9])+([.a-zA-Z0-9_-])*@([a-zA-Z0-9_-])+(.[a-zA-Z0-9_-]+)+/' , $email_address)) {
echo 'ERROR: Cant send an email. Check the email address!';
} else {
$header = 'MIME-Version: 1.0'."\r\n";
$header .= 'Content-type: text/html; utf-8'."\r\n";
$header .= "From: backup@{$_SERVER['SERVER_NAME']}\r\n" . "Reply-To: backup@{$_SERVER['SERVER_NAME']}\r\n";
mail ($email_address,$site_title,$message,$header ) or die('ERROR: Cant send an email!');
}
}
// get the formated size of a file
function getFilesize ($file) {
$fileSizeNames = array(' Bytes', ' kB', ' MB', ' GB', ' TB');
$size = filesize($file);
$i = 0;
while ( $size > 1024 ) {
$i++;
$size = $size / 1024;
}
$size = round($size,2);
$size = str_replace('.', ',', $size);
return "$size $fileSizeNames[$i]";
}
// EOFDie Variablen ganz oben müsst Ihr entsprechend anpassen, dazu habe ich einen Kommentar hinter jede Variable geschrieben. Ebenso könnt Ihr die Liste der Verzeichnisse/Dateien an Eure Bedürfnisse anpassen.
Auch kann es sein, dass bei Euch die Befehle tar, rm, mkdir in anderen Pfaden liegen, dann müsst Ihr dies entsprechend anpassen. Wo ein Befehl unter Unix liegt, könnt Ihr mit which herausfinden, z.B.: "which tar".
3. Schritt
Dieses Script wird nun in den Cronjob eingebunden. Da es vom PHP-Interpreter ausgeführt werden muss, sieht der Befehl dann z.B. so aus:
/usr/bin/php /home/backup.phpBei mir wird das Script wöchentlich (jeweils Donnerstags 2 Uhr) ausgeführt.
4. Schritt
Jetzt kümmern wir uns darum, dass die Dateien auf den lokalen Rechner gelangen. Dazu installiert Ihr Euch zunächst NCFTP. Das ist ein Kommandozeilen-FTP-Client, welcher für verschiedene Betriebssysteme verfügbar ist und etwas einfacher als die Standard-Tools.
Nach der Installation kann auf der Konsole/Eingabeaufforderung folgender Befehl genutzt werden, um Euer Backup vom FTP-Server zu holen:
ncftpget -u FTP-USER -p FTP-PASSWORT FTP-SERVER LOKALER-PFAD /home/backups/*Die groß-geschriebenen Worte sind dabei durch Eure Daten zu ersetzen. Das Verzeichnis /home/backups/ müsst Ihr auch ändern, falls Ihr im Script ein anderes Verzeichnis für die Backups angegeben habt.
5. Schritt
Wenn Ihr wie ich mehrere Installationen zu sichern habt, könnt Ihr Euch eine kleine Batch-Datei schreiben, wo Ihr ncftpget hintereinander mehrfach ausführt. Im folgenden Beispiel werden also 3 verschiedene Backups geholt und in meine lokalen Backup-Verzeichnisse gespeichert:
ncftpget -DD -u user1 -p passwort1 ftp-server1.de d:\kunde1\backups /home/backups/*
ncftpget -DD -u user2 -p passwort2 ftp-server2.de d:\kunde2\backups /home/backups/*
ncftpget -DD -u user3 -p passwort3 ftp-server3.de d:\kunde3\backups /home/backups/*Der Parameter -DD bewirkt, dass die heruntergeladenen Dateien im Anschluss auf dem FTP-Server gelöscht werden. So vermeide ich Probleme durch Speicherplatz-Limits.
Euch sollte bewusst sein, dass in dieser Batch-Datei die FTP-Passwörter im Klartext stehen. Bei mir liegt diese Datei deshalb in einem TrueCrypt-Container. Ich führe diese Batch-Datei nun jeden Freitag vormittag aus, bevor ich den ganz normalen Backup-Prozess für meinen lokalen Rechner starte.
Mir ist klar, dass diese Vorgehensweise nicht für jeden von Euch die optimale Lösung darstellt, aber vielleicht dient es dem ein oder anderen als Anregung für eine eigene Sache ...
Arbeitet bei conversearch GmbH: http://conversearch.de (Webseiten-Analyse und -Monitoring)
Bloggt bei Andiministrator.de: http://andiministrator.de
Offline
#2 18. Januar 2011 21:55
- nockenfell
- Moderator

- Ort: Gontenschwil, Schweiz
- Registriert: 09. November 2010
- Beiträge: 2.935
- Webseite
Re: Automatisiertes Backup - ein Ansatz
Ich habe mir hier eine ein wenig aufwändigere Lösung geschrieben welche ich aktuell am testen bin:
- Backup der Files und der MySQL DB per exec
- Automatisches Upload der Files auf mein NAS
- Automatisches Löschen der Files auf dem NAS nach einer bestimmten Anzahl Backups
Das gesamte Script läuft über PHP und ist somit recht unabhängig von der Umgebung. Voraussetzung sind
- Cronjobs
- exec
Bei Interesse dokumentiere ich mein Script und stelle es auch zur Verfügung.
[dieser Beitrag wurde mit 100% recycled bits geschrieben]
Mein Blog / Diverse Links rund um CMS Made Simple
Module: btAdminer, ToolBox
Offline
#3 18. Januar 2011 22:41
- Andynium
- Moderator

- Ort: Dohna / SN / Deutschland
- Registriert: 13. September 2010
- Beiträge: 7.018
- Webseite
Re: Automatisiertes Backup - ein Ansatz
Klingt interessant - hab schon überlegt, das Posting in das HowTo-Board zu verschieben ...
Offline
#4 20. April 2011 14:09
- Andynium
- Moderator

- Ort: Dohna / SN / Deutschland
- Registriert: 13. September 2010
- Beiträge: 7.018
- Webseite
Re: Automatisiertes Backup - ein Ansatz
Bei Interesse dokumentiere ich mein Script und stelle es auch zur Verfügung.
Hast du brauchbare Ergebnisse erzielt?
Offline
#5 20. April 2011 19:56
- nockenfell
- Moderator

- Ort: Gontenschwil, Schweiz
- Registriert: 09. November 2010
- Beiträge: 2.935
- Webseite
Re: Automatisiertes Backup - ein Ansatz
Ja und Nein. Das Script ist derzeit nur auf dem von mir genutzten System wirklich lauffähig. In letzter Zeit habe ich mir nicht die Mühe gemacht es zu verbessern. So fehlen im Moment einige Prüfungen welche anzeigen ob es funktioniert und wenn nicht, warum nicht.
Aber das wird dann mal noch was.
[dieser Beitrag wurde mit 100% recycled bits geschrieben]
Mein Blog / Diverse Links rund um CMS Made Simple
Module: btAdminer, ToolBox
Offline
#6 10. Juni 2011 16:56
- jeff1980
- Server-Pate
- Ort: Dortmund
- Registriert: 26. November 2010
- Beiträge: 630
Re: Automatisiertes Backup - ein Ansatz
Hi,
hab das Script nun auch bei mir installiert - da ich für MySQL schon den MySQLDumper konfiguriert habe, habe ich die ensprechenden Zeilen einfach rausgelassen.
Das Script läuft echt super - auch als Cron Job.
Allerdings lassen nicht alle Pakete, die ich betreue, Cron Jobs zu. Gibt es da andere Möglichkeiten? Ich habe hier einen Windows-Server laufen - kann ich von dort aus das Script anstoßen? Hab dazu immer nur Ansätze mit XAMPP gesehen. Aber das Script liegt ja außerhalb des Servers.
Oder gibt es einen guten Anbieter für externe Cron Jobs? Traue denen irgendwie nicht ...
Offline
#7 10. Juni 2011 17:48
- Andynium
- Moderator

- Ort: Dohna / SN / Deutschland
- Registriert: 13. September 2010
- Beiträge: 7.018
- Webseite
Offline
#8 11. Juni 2011 08:49
- jeff1980
- Server-Pate
- Ort: Dortmund
- Registriert: 26. November 2010
- Beiträge: 630
Re: Automatisiertes Backup - ein Ansatz
Hi,
pycron (http://www.kalab.com/freeware/pycron/pycron.htm) hats gebracht - mit diesem Aufruf kann man externe php-Scripte starten:
0 20 * * * "C:\Program Files (x86)\Internet Explorer\IEXPLORE.EXE" http://pfad-zum-backupscript.de/backup-script.phpWobei die ersten 5 Werte für Minute, Stunde, Tag, Monat, Wochentag stehen.
Was mich nun noch ein bisschen stört:
Damit das Script aufgerufen werden kann, konnte ich den Ordner mit dem Script nicht per htaccess schützen. Es stehen zwar keine Datenbankinformationen drin, da ich dass nicht über dieses Script realisiere. Aber schön ist es trotzdem nicht.
Leider konnte ich nicht herausfinden, wie ich in der Kommandozeile für pycron eine Anmeldung einbauen kann.
http://benutzer:passwort@pfad-zum-backupscript.de/backup-script.php funktioniert naturgemäß nicht.
Ich weiß, immer was anderes 
Aber ansonsten klappt es, auch mit dem NCFTP, sehr gut. Um das Ganze komplett automatisiert laufen zu lassen, benötigt man aber definitiv einen eigenen Server - auch wenns nur ein File-Server ist.
Edit: Mit Firefox funktioniert zwar die Krücke mit Passwort in der URL - allerdings fragt er jedes Mal ab, ob es auch wirklich passieren soll. Hilft also leider auch nicht.
Passwort speichern habe ich natürlich auch schon probiert - bringt auch nichts...
Beitrag geändert von jeff1980 (11. Juni 2011 08:53)
Offline
Seiten: 1