Automatisches Datenbank-Backup mit Cronjobs bei All-Inkl

Wenn man eine Website/Web-Applikation betreibt, die auf eine SQL-Datenbank zurückgreift, macht es definitiv Sinn regelmäßig automatisiert eine Sicherung der Datenbank anzulegen. Nicht nur als Schutz, falls man selber etwas zerlegt, sondern natürlich auch falls z. B. ein Update des verwendeten CMS fehlschlägt oder ein Hacker es schafft die Datenbank zu löschen. Wie man dies mit Hilfe eines CronJobs erledigt zeige ich in diesem Artikel.

 

Ordner-Konfiguration

Wenn man seinen Webspace bei All-Inkl hat, sind Cronjobs ab dem PrivatPlus-Paket inklusive. Als erstes sollte man in einem der vorhandenen Ordner einer Domain einen per htaccess-Datei mit Passwort geschützten Ordner namens „intern“ oder dergleichen anlegen. Dieser Ordner ist dann am besten nur für Skripte, die als Cronjob genutzt werden, zu verwenden. Hintergrund ist, dass die Skripte für den Cronjob unter einer der Domains „von außen“, also z. B. unter domain.de/intern/backup.phpx, erreichbar sein muss.  Auf die Einrichtung gehe ich an dieser Stelle nicht weiter ein.

Für die Ablage der Backup-Dateien habe ich einen Ordner namens backups, mit entsprechenden Schreibrechten, außerhalb der Ordner der einzelnen Domains angelegt. Dieser ist von außen also nur per FTP zu erreichen oder durch die auf dem Server ausgeführten Skripte. Das heißt, in meinem Beispiel kann die Skript-Datei unter keinen Umständen in dem Ordner backups, der sich außerhalb der Domain-Ordner befindet, abgelegt werden. Denn dann könnte man auf diese Datei nicht durch einen Cronjob zugreifen.

 

Skript

Für das Anlegen der Backups benutze ich folgenden Code:

Die Funktionsweise ist recht simpel: Die Zugangsdaten zu allen zu sichernden Datenbanken werden im Array $databases hinterlegt. Da bei All-Inkl der Datenbank-Name immer auch dem Namen des Datenbank-Nutzers entspricht, braucht man hier keine Unterscheidung zu machen. Der unter „export“ angegebene Text wird nur für die Benennung der abgelegten Dump-Datei im Backup-Ordner verwendet und hat ansonsten keinerlei Relevanz. Deshalb bietet sich es hier an den jeweiligen Domain-Namen zu verwenden. Mit Hilfe von Exec wird der Dump für jede konfigurierte Datenbank erstellt und anschließend gezippt.

In der Variable $sql_file wird der Ausgabepfad, basierend auf dem Serverpfad zum Ordner backups und dem unter „export“ angegebenen Begriff und dem Zeitpunkt der Erstellung, gebildet. Die verwendete Nutzerkennung w123456 muss natürlich noch abgeändert werden in die eigene Benutzerkennung bei All-Inkl. Allerdings muss dies nicht unbedingt der Name des FTP-Accounts sein, wenn man diesen selbständig anders benannt hat. Die Pfadangabe geht stets von der obersten Ebene des Servers aus. Unter dem Ordner htdocs ist für jeden Nutzer bzw. Account bei All-Inkl ein einzelner Ordner angelegt, in welchem der jeweilige Nutzer Schreibrechte hat und seine Dateien ablegt. Das Präfix dump_ wird vor den Namen jeder erstellten Backup-Datei geschrieben, die ausgegebene Backup-Datei heißt dann z. B. dump_devilatwork_20190301_2300.sql.gz. Dies kann beliebig geändert oder auch ganz weggelassen werden.

Wichtig: Die Skript-Datei darf aufgrund der Verwendung von Exec nicht als PHP-Datei gespeichert sein, da All-Inkl dies verbietet. Stattdessen muss diese mit der Endung „.phpx“ gespeichert werden. Mehr dazu erfährt man in der All-Inkl-FAQ

 

Cronjob-Konfiguration

Im KAS von All-Inkl legt man den Cronjob unter Tools > Cronjobs an:

Dort gibt man die URL zum auszuführenden Skript an (auf das richtige Protokoll achten!). Für das Passwort des per htaccess geschützten Ordners verwendet man am besten kein zu langes Passwort und auch keine Sonderzeichen, damit bekam ich immer Fehlermeldungen beim Versuch den Cronjob anzulegen. Diese Zugangsdaten sind hier unten einzutragen:

An die hinterlegte E-Mail-Adresse wird die Text-Ausgabe des Skriptes geschickt.

 

Vielleicht hilfreich für den einen oder anderen:

Die angegebene maximale Anzahl an Cronjobs bei All-Inkl ist übrigens eigentlich irrelevant, da man sich auch ein Skript schreiben kann, das zu bestimmten Uhrzeiten andere Tasks ausführt oder andere Skripte per include einbindet. Dieses Skript kann man dann mit einem einzigen Cronjob z. B. jede Stunde ausführen lassen. Entweder wird dann eine Aufgabe ausgeführt oder nicht. Somit reicht eigentlich ein einziger Cronjob um Hunderte Aufgaben zu bewältigen.

6 Kommentare

  1. Avatar
    Troy März 20, 2019 5:05 pm  Antworten

    Hi Tobias,

    super Artikel. Ich bin ein ziemlicher Amateur was dieses Zeug betrifft, bin aber dabei mich immer weiter reinzuarbeiten.

    Ich habe noch drei Unklarheit weshalb es bei mir wahrscheinlich auch nicht funktioniert…

    1. Muss bei der .phpx Datei noch etwas anderes angepasst werden als die jeweiligen Datenbanken in den arrays, wie z.B. der folgende Ausschnitt?
    foreach ($databases as $nr => $database){
    $sql_file = /www/htdocs/w123456/backups/dump_ . $database[‚export‘] . „_“ . date(‚Ymd_Hi‘) . „.sql“;
    $db_name = $database[’name‘];
    $db_pass = $database[‚pass‘];

    Ich denke, dass der fett makierte Bereich das FTP Verzeichnis ist wo die Datei zur Durchführung des Cronjobs liegt. Aber wieso steht dahinter dann „/dump_“, wenn in deinem Beispiel die Datei doch „backup.phpx“ genannt wurde?

    Der Abschnitt „w123456“ muss wahrscheinlich an den eigenen FTP Benutzernamen angepasst werden oder?

    2. Außerdem würde ich gerne wissen welchen Pfad ich bei der Einstellung des Cronjobs auf der All-Inkl. Seite angeben muss. Ist es richtig, dass ich dort nach dem gegebenen https:// „server/backups/backup.phpx“ angeben muss? „server“ steht für den Domainnamen mit dem man sich auch per Filezilla ins FTP einloggt und der Ordner „backups“ mit der Datei „backup.phpx“ sind wie in deinem Beispiel außerhalb der Domainverzeichnisse angelegt worden.

    3. Woher weiß der Cronjob, dass er die Backups unter den jeweiligen Domainverzeichnissen in den Ordner „intern“ packen soll? Dazu finde ich keinen Code.

    Ich hoffe, dass ich dich nicht überrumple mit meinen Fragen… Hilfe wäre super nett!

    • Tobias Langner
      Tobias Langner März 20, 2019 11:42 pm  Antworten

      Hallo Troy,

      danke für das positive Feedback. Kein Problem, jeder fängt mal an 😉

      zu Punkt 1)

      w123456 muss abgeändert werden, das ist richtig. Allerdings muss dies nicht unbedingt der Name des FTP-Accounts sein. Standardmäßig ist er es, solange man dort nicht selbständig etwas anderes konfiguriert hat.

      Lediglich das immer wieder automatisch auszuführende Skript heißt backup.phpx. Das dump_ wird vor den Namen jeder erstellten Backup-Datei geschrieben, die ausgegebene Backup-Datei heißt dann z. B. dump_devilatwork_20190301_2300.sql

      Die Pfadangabe geht von der obersten Ebene des Servers aus. Unter htdocs ist für jeden Nutzer bzw. Account ein einzelner Ordner angelegt, in welchem der jeweilige Nutzer Schreibrechte hat.

      zu Punkt 2)

      Wo das Skript abgelegt wird, habe ich im Artikel anscheinend nicht vernünftig erklärt, sorry. Der Ordner intern ist nur für das Skript gedacht. Das werde ich im Artikel auch ergänzen:

      Die Datei backup.phpx muss unter einer der Domains „von außen“, also z. B. unter domain.de/intern/backup.phpx, erreichbar sein. Das heißt, diese kann in meinem Beispiel nicht in dem Ordner backups, der sich außerhalb der Domain-Ordner befindet, abgelegt werden. Der öffentliche Ordner, in den man dieses Skript legt, kann aber per htaccess-File vor Zugriffen von Unbefugten geschützt werden.
      Der bei All-Inkl einzutragende Link wäre dann https://domain.de/intern/backup.phpx, zusätzlich gibt man (wie oben beschrieben) die Logindaten die man per htaccess und htpasswd definiert hat an.

      Grundsätzlich könnte man natürlich den Ordner backups, in den die Datenbank-Dumps geschrieben werden, auch in einen per htaccess abgeischerten Ordner legen, der „öffentlich“ unter einer der Domains erreichbar ist. Aus Sicherheitsgründen würde ich aber davon abraten, wenn das nicht aus irgendeinem Grund wirklich erforderlich ist. Da der Download der Backups, zumindest bei mir, aber sowieso per FTP erfolgt, sehe ich da keinen Grund für.

      zu Punkt 3)

      Ich denke das ist in meinem Artikel nicht ganz deutlich geworden, wie schon mit dem Ordner intern:

      Die Backups werden nicht in den Ordner intern bzw. auch nicht in einen Ordner unterhalb des jeweiligen Domain-Verzeichnisses abgelegt, sondern in den Ordner backups, z. B. so:

      dump_domain1_xxxxx.sql
      dump_domain2_xxxxx.sql

      Die Struktur, wenn man sich per FTP aufschaltet, müsste ungefähr so aussehen:

      – backups
      — dump_domain1_xxxxxx.sql
      — dump_domain2_xxxxxx.sql
      – domain1
      — intern
      — backup.phpx
      – domain2
      – domain3
      – domain4

      Ich hoffe das hat es etwas deutlicher gemacht 😉

      mfg
      Tobias

  2. Avatar
    Troy März 25, 2019 4:44 pm  Antworten

    Hi Tobias,

    danke für deine sehr ausführliche Antwort. Jetzt habe ich das ganze denke ich verstanden.

    Kann es sein, dass All-Inkl. einige Zeit benötigt um den Cronjob einzurichten? Ich habe das Skript nun korrigiert und wollte einen Testdurchlauf machen, indem ich den Cronjob auf 2min. später gesetzt habe. Leider funktionierte es nicht. Oder gibt es andere denkbare Fehlerquellen?

    Zudem noch eine Frage zum Skript:

    Bei der Zeile „export“ => „db1“, ist die „db1“ doch das Kommentar der jeweiligen Datenbank welches man über All-Inkl. hinzugefügt hat oder ist dies vielleicht meine Fehlerquelle?

    Gruß & vielen Dank nochmal!

    • Tobias Langner
      Tobias Langner März 25, 2019 8:27 pm  Antworten

      Hallo Troy,

      kein Problem. Als ich den Artikel 1,5 Jahre später nochmal durchgelesen habe war es mir auch nicht mehr direkt klar, immerhin läuft das Skript bei mir seitdem nur noch durch 😀

      Also, das was du bei export angibst ist an sich völlig egal. Der Inhalt von export hat bei All-Inkl keine Bewandnis. Hierüber definierst du nur den Namen der Dump-Datei, die durch das Skript erstellt wird.

      Für meinen Blog könnte das z. B. so aussehen:

      $databases[] = array(
      „export“ => „devilatwork“,
      „name“ => „d123456a“,
      „pass“ => „1234567890“
      );

      Ergebnis: Die Datei heißt z. B. dump_devilatwork_20190325_0300.sql bzw. dump_devilatwork_20190325_0300.sql.gz nach dem Komprimiervorgang.

      Dass es länger dauert bis die Änderungen bei den CronJobs übernommen werden habe ich so nicht mehr in Erinnerung, kann aber gut sein, dass dies daran liegt, dass immer nur alle paar Sekunden oder Minuten die entsprechenden Config-Dateien entsprechend der gemachten Änderungen im Backend durch All-Inkl aktualisiert werden.

      Wenn du das Skript am Laufen hast, sind vielleicht noch folgende Artikel zu einem automatischen Download der Backup-Files für dich interessant:

      https://blog.devilatwork.de/automatischer-download-der-datenbank-backups/

      https://blog.devilatwork.de/automatischer-backup-download-per-winscp-und-das-aktualisierte-server-zertifikat/

      mfg
      Tobias

  3. Avatar
    Hannes Mai 7, 2019 2:13 pm  Antworten

    Danke für Deinen Blogbeitrag. All-Inkl schreibt dazu (etwas versteckt) auch ein paar Sachen:

    Datensicherung

    Ist evtl. für den ein oder anderen interessant. Im Endeffekt sollten beide Scripte gleich gut funktionieren.

    • Tobias Langner
      Tobias Langner Mai 7, 2019 10:12 pm  Antworten

      Hallo Hannes,

      danke für deinen Kommentar. Das in dem Beitrag genannte Filesizelimit müsste ich wohl mal überprüfen. Noch sind meine zu sichernden Datenbanken sehr klein, aber vielleicht wird das irgendwann mal kritisch.

      mfg
      Tobias

Schreibe einen Kommentar