heimseiten/contao-backup-bundle

„Sicherung" im Backend (unter System): Datenbank-Backup und alle relevanten Dateien/Ordner als ZIP herunterladen.

Maintainers

Package info

github.com/heimseiten/contao-backup-bundle

Type:contao-bundle

pkg:composer/heimseiten/contao-backup-bundle

Statistics

Installs: 10

Dependents: 0

Suggesters: 0

Stars: 1

Open Issues: 0

1.0.5 2026-06-22 19:11 UTC

This package is auto-updated.

Last update: 2026-06-22 19:13:46 UTC


README

Contao Backup Bundle

Contao Backup Bundle

Fügt im Backend unter System den Punkt „Sicherung" hinzu, mit drei Downloads (unter jedem Button steht, was genau enthalten ist):

  • Datenbank und Dateien herunterladen – ein ZIP mit dem Datenbank-Backup (unter database/) und allen relevanten Dateien/Ordnern.
  • Nur Dateien herunterladen – die Dateien/Ordner als ZIP.
  • Nur Datenbank herunterladen – das Datenbank-Backup (Contaos eigenes Backup, gzip-komprimiertes SQL; wird zusätzlich in var/backups abgelegt).

Enthaltene Pfade (Dateien- und Voll-Backup)

Pfad Inhalt
composer.json, composer.lock Abhängigkeiten / exakte Versionen
config/ App-Konfiguration (Symfony/Bundles)
contao/ DCA, Templates, Sprachen …
src/ Eigener Anwendungscode (App-Namespace)
templates/ Globale Templates
translations/ Eigene Symfony-Übersetzungen
migrations/ Eigene Doctrine-Migrationen
system/config/localconfig.php Systemeinstellungen (Legacy)
files/ Medien / Dateiverwaltung – inkl. aller Erweiterungs-Uploads (Isotope-Produktbilder, MetaModels-Dateifelder …)

Nicht vorhandene Pfade werden übersprungen.

Warum reicht das? Erweiterungen wie Isotope oder MetaModels legen ihre Daten in der Datenbank ab (im DB-Backup enthalten) und ihre hochgeladenen Dateien unter files/ (ebenfalls enthalten). Ihr Code steckt in vendor/ und wird über composer.json/composer.lock jederzeit per composer install wiederhergestellt – ein Backup von vendor/ ist daher unnötig. Genauso bewusst ausgelassen: var/ (Cache/Logs, regeneriert sich) und public/ (Einstiegspunkt + per contao:install/assets:install neu erzeugte Assets).

Sicherheit

Ein Backup ist per Definition eine vollständige Kopie aller sensiblen Daten – behandle die heruntergeladene Datei entsprechend.

  • Nur Administratoren. Serverseitig per isAdmin geprüft; Nicht-Admins erhalten 403.
  • Hinter der Backend-Firewall – nur authentifizierte Backend-Sitzungen.
  • CSRF-geschützt: Die Downloads laufen über POST-Formulare mit Contao-Request-Token; ein ungültiges/fehlendes Token wird vom Core mit 403 abgewiesen.
  • Feste Pfade, keine Benutzereingabe → kein Path-Traversal. Symlinks werden nicht gefolgt (kein Ausbrechen aus dem Projektverzeichnis).
  • Kein Temp-Artefakt: Das ZIP wird direkt zum Browser gestreamt und nie auf die Platte geschrieben. Das DB-Backup landet (durch Contao) zusätzlich in var/backups – außerhalb des Web-Roots, per URL nicht erreichbar, von Contaos Retention bereinigt.
  • Aber: Die heruntergeladene Datei enthält u. a. Passwort-Hashes, 2FA-Geheimnisse, Mitglieder-/Personendaten und localconfig.php. Sie ist unverschlüsselt – sicher (idealerweise verschlüsselt) aufbewahren, nur über HTTPS laden, nicht ungeschützt in Cloud-Ordnern ablegen.

Große Installationen & PHP-Limits

Das ZIP wird mit ZipStream direkt zum Browser gestreamt – kein Temp-ZIP auf der Platte, kein Warten auf einen kompletten Build. Damit sind die üblichen Stolperfallen bei großen files/-Ordnern entschärft:

  • Arbeitsspeicher (memory_limit): unkritisch. Dateien werden von der Platte direkt in den Stream geschoben – es liegt nie eine ganze Datei oder das ganze ZIP im PHP-Speicher. Auch Multi-GB-Backups laufen mit kleinem memory_limit.
  • Kein temporärer Speicherplatz nötig. Es wird nichts zwischengespeichert; der Download beginnt sofort.
  • Read-/Request-Timeouts: Weil ab der ersten Sekunde Bytes fließen, greift der Webserver-Read-Timeout (nginx fastcgi_read_timeout, Apache FcgidIOTimeout) nicht. Das Bundle hebt zusätzlich set_time_limit(0) auf und packt ohne Re-Kompression (Medien sind ohnehin komprimiert). Ein hartes Gesamtlimit wie PHP-FPM request_terminate_timeout bleibt ein serverseitiges Thema – ist aber selten so knapp gesetzt.
  • ZIP > 4 GB: automatisch über ZIP64.

Fortschrittsbalken direkt auf der Seite: In Chrome/Edge wird der Download per JavaScript über die File System Access API direkt auf die Platte gestreamt – mit einem Fortschrittsbalken samt Prozent/MB im Backup-Modul selbst. Die Prozentangabe ist exakt, weil die ZIP-Größe vorab in einem schnellen Durchlauf ermittelt (nur ein stat pro Datei, kein Inhalt – bei z. B. ~1.750 Dateien unter einer halben Sekunde) und als Content-Length gesendet wird. Firefox/Safari fallen automatisch auf den normalen Browser-Download zurück (Fortschritt dann im Download-Manager des Browsers). Einzige Konsequenz: Ändert eine Datei während des (evtl. langen) Downloads ihre Größe, kann das ZIP unvollständig sein – dann einfach erneut laden.

Abgestufte Fallbacks (Progressive Enhancement): Die Buttons sind echte <form method="post">ohne JavaScript lädt ein Klick das Backup ganz normal herunter (der Server streamt, der Browser zeigt seinen eigenen Fortschritt). Bricht der JavaScript-Download ab (Speicherdialog nicht verfügbar, Platte voll, Netzfehler), wird die halbe Datei verworfen und automatisch auf den normalen Browser-Download umgeschaltet. Nur ein echter Serverfehler (z. B. abgelaufenes Request-Token) wird als Fehler gemeldet.

Fehlersuche

Schlägt ein Download fehl, wird der Grund protokolliert – im Backend unter System › System-Log und in var/logs/. Häufigste Ursache auf produktiven Servern: var/backups/ ist für den Webserver-Benutzer nicht beschreibbar (Contao legt dort das Datenbank-Backup ab) → Meldung „Unable to write to backups/…". Abhilfe: Schreibrechte auf var/ bzw. var/backups/ setzen. (Der reine Dateien-Download funktioniert davon unabhängig, weil er kein Datenbank-Backup erzeugt.)

Fortschrittsbalken bleibt leer / nur MB statt Prozent: Der Server komprimiert die Antwort (gzip, z. B. Apache mod_deflate). Beim Gzippen einer gestreamten Antwort wirft der Server die Content-Length weg, sodass der Browser die Gesamtgröße nicht kennt. Das Bundle erkennt das automatisch und blendet auf der Sicherung-Seite einen Hinweis ein. Für den Prozent-Balken die Kompression für den Download abschalten – in public/.htaccess:

<IfModule mod_setenvif.c>
    SetEnvIf Query_String "do=backup" no-gzip dont-vary
</IfModule>

Der Download selbst ist davon nie betroffen, nur die Prozentanzeige.

Installation

composer require heimseiten/contao-backup-bundle

Anschließend erscheint im Backend unter System der Punkt „Sicherung" (für Administratoren).