Überblick
Das Problem
Eine Contao-Installation, die produktiv läuft, wird selten aktualisiert — und genau das ist der Kern des Problems. Je länger der letzte Composer-Lauf zurückliegt, desto größer wird der Sprung, und desto mehr hängt an einem einzigen Kommando, das man irgendwann abends über SSH absetzt und dann hofft, dass es durchläuft.
- Das Zeitfenster ist nicht planbar.
composer updatedauert je nach Paketzahl und Hoster zwischen zwei und zwanzig Minuten. Läuft es im Browser, reißt irgendwann das PHP-Timeout, und man weiß nicht, ob der Vorgang abgeschlossen ist oder mittendrin abgebrochen wurde. - Der Rückweg ist nicht vorbereitet. Ein Backup vor dem Update ist eine Aufgabe, die man vergisst oder auf „mache ich gleich noch" verschiebt. Wenn das Update die Seite zerlegt, stellt sich heraus, dass das letzte Backup vom Hoster stammt, zwei Tage alt ist und über ein Support-Ticket beantragt werden muss.
- Nach einem kaputten Update fehlt der Zugang. Ein fehlgeschlagenes
Update trifft üblicherweise
vendor/. Danach bootet Symfony nicht mehr, also bootet Contao nicht mehr, also gibt es kein Backend — und jedes Werkzeug, das im Backend liegt, ist genau in dem Moment weg, in dem man es braucht. - Auf Shared Hosting stimmen die PHP-Versionen nicht überein.
Bei Plesk läuft der Webserver über
/opt/plesk/php/8.4/sbin/php-fpm, die CLI liegt unter/opt/plesk/php/8.4/bin/php. Ruft man Composer über einen Shell-Wrapper auf, erwischt man womöglich eine andere PHP-Version mit anderen Extensions als die, unter der die Seite tatsächlich läuft. - Man sieht nicht, was überhaupt anliegt. Ob ein Paket verlassen („abandoned") ist, ob eine neuere Version existiert und ob sie wegen der Constraints anderer Pakete überhaupt installierbar wäre, steht in keinem Backend-Bildschirm — man erfährt es erst, wenn Composer sich weigert.
- Regelmäßige Backups sind Handarbeit. Ohne Automatisierung entsteht eine Sicherung nur dann, wenn jemand daran denkt. Das ist der Zustand, in dem sich die meisten kleinen und mittleren Contao-Installationen befinden.
Am härtesten trifft es Agenturen und Freelancer, die eine zweistellige Zahl fremder Installationen betreuen, auf Hosting-Umgebungen, die sie sich nicht ausgesucht haben, und die im Ernstfall nachts erreichbar sein müssen.
Die Lösung
Guardian verlegt Update und Restore aus dem Browser-Request in einen eigenständigen Hintergrundprozess und legt daneben einen zweiten, framework-freien Zugang, der auch dann noch funktioniert, wenn Contao nicht mehr bootet.
Strukturell ändert sich dadurch dreierlei. Erstens läuft ein Update als Job in einem eigenen PHP-CLI-Prozess, losgelöst vom Webserver-Timeout; das Backend fragt nur noch Status und Log ab. Zweitens wird der Snapshot nicht mehr optional nebenher erstellt, sondern ist ein fester Schritt der Update-Pipeline, der vor jeder Änderung läuft. Drittens liegt das Wiederherstellungswerkzeug bewusst außerhalb von Contao — eine einzelne PHP-Datei, die der Webserver direkt ausliefert.
| Aufgabe | Ohne Guardian | Mit Guardian |
|---|---|---|
| Update ausführen | SSH, composer update im Terminal, Verbindung offen halten |
Job im Backend starten; läuft im eigenen Prozess weiter, Browser kann zu |
| Update vorher testen | Kopie der Seite aufsetzen | Dry-Run: composer update --dry-run und contao:migrate --dry-run |
| Backup vor dem Update | Manueller Schritt, der oft ausfällt | Pre-Update-Snapshot als fester erster Schritt jeder Pipeline |
| Regelmäßige Backups | Hoster-Backup oder gar keins | Zwei getrennte Zeitpläne (Mini / Full) über Contaos Cron-System |
| Wiederherstellen nach kaputtem Update | Backend weg — Ticket beim Hoster, Datenbank-Import von Hand | Standalone-Panel im Webroot, arbeitet ohne Contao, Symfony oder Composer |
| Überblick über Paketstand | composer outdated über SSH |
Paketübersicht im Backend, direkt gegen Packagist, 24 h gecacht |
Zugeordnet zu den Punkten oben:
- Zeitfenster → Update-Jobs: eigener CLI-Worker mit aufgehobenem Zeitlimit, Fortschritt per Polling.
- Rückweg → Pre-Update-Snapshot: erster Schritt der Pipeline, mit Ein-Klick-Rollback, wenn der Job fehlschlägt.
- Fehlender Zugang → Standalone-Recovery-Panel: eine PHP-Datei ohne Abhängigkeiten, eigene Token-Authentifizierung.
- PHP-Versionen → PHP-CLI-Einstellungen: der Pfad zur
CLI-Binary ist im Backend konfigurierbar; Composer läuft immer als
<konfiguriertes PHP> composer.phar, nie über einen Shell-Wrapper. - Sichtbarkeit → Vorabprüfung und Paketübersicht.
- Handarbeit → Geplante Backups mit Aufbewahrungsgrenze und optionaler E-Mail-Benachrichtigung.
Wann das Paket passt
| Situation | Einschätzung |
|---|---|
| Contao 5.3+ auf Shared Hosting (Plesk, cPanel, DirectAdmin) | Passt. Genau dafür gebaut — inklusive konfigurierbarem
CLI-Pfad und Fallbacks, wenn mysqldump oder tar fehlen. |
| Agentur betreut mehrere fremde Installationen | Passt. Backup, Update und Notfallzugang ohne SSH auf jeder Installation — pro Installation allerdings eine eigene Lizenz, gebunden an deren Domain. |
| Redaktionsseite ohne Entwickler im Haus | Passt. Vorabprüfung und Dry-Run zeigen vor jeder Änderung, was passieren würde. |
| Sie wollen nur regelmäßige Datenbank-Backups, sonst nichts | Passt, aber prüfen Sie die Alternativen. Geplante Backups
sind Pro. Contao bringt mit contao:backup:create bereits einen
eigenen Datenbank-Backup-Befehl mit, den ein Server-Cron direkt aufrufen kann. |
Deployment läuft über Git und CI/CD, vendor/ wird im Build erzeugt |
Eher nicht. In dieser Aufstellung gehört das Update in die Pipeline, nicht ins Backend der Produktivinstallation. Guardian würde gegen Ihren Deployment-Prozess arbeiten. |
Mehrere Knoten hinter einem Loadbalancer ohne gemeinsames var/ |
Nicht geeignet. Lizenzzustand, Job-Ablage und Replay-Ledger
liegen im Dateisystem unter var/ und setzen einen gemeinsamen,
transaktionalen Speicher voraus. |
| Contao 4.13 oder älter | Nicht geeignet. contao/core-bundle: ^5.3 ist
eine harte Anforderung. |
Hosting ohne PHP-Extension sodium |
Nicht nutzbar. Ohne sodium kann keine Lizenz
verifiziert werden; die Installation bleibt unlizenziert (fail closed). |
Teil 1 — Einrichtung
Der Weg von der Installation bis zum ersten verwendbaren Backup:
- Voraussetzungen prüfen
- Vor der Installation: sichern und entscheiden
- Installation über den Contao Manager — oder über Composer
- Installation überprüfen
- Lizenz aktivieren
- PHP-CLI-Pfad konfigurieren
- Das erste Backup erstellen
Voraussetzungen
Aus composer.json des Pakets.
| Anforderung | Version | Anmerkung |
|---|---|---|
| PHP | ^8.2 |
Zusätzlich wird eine erreichbare PHP-CLI-Binary benötigt. |
contao/core-bundle |
^5.3 |
— |
ext-json |
— | In praktisch jeder PHP-Installation vorhanden. |
ext-sodium |
— | Erforderlich für die Ed25519-Signaturprüfung der Lizenz. Fehlt sie, bleibt die Installation unlizenziert. |
symfony/process |
^6.4 || ^7.0 |
Start des Hintergrund-Workers. |
symfony/console |
^6.4 || ^7.0 |
— |
symfony/http-client |
^6.4 || ^7.0 |
Kommunikation mit dem Lizenzserver. |
Nicht erzwungen, aber empfohlen:
| Werkzeug | Wofür | Wenn es fehlt |
|---|---|---|
mysqldump / mysql |
Datenbank sichern und zurückspielen | Ein PHP-basierter Fallback übernimmt. |
tar |
Verzeichnisse archivieren (gzip) | Ein ZipArchive-Fallback übernimmt. |
composer.phar |
Update-Jobs | Updates lassen sich nicht ausführen. Pfad ist konfigurierbar. |
exec() nicht in disable_functions |
Worker-Start, PHP-Binary-Test | Der Test der PHP-Binary meldet „Cannot test: exec() is in disable_functions." |
Vor der Installation
- Sichern Sie die Installation außerhalb von Guardian. Das erste Guardian-Backup entsteht erst nach der Einrichtung. Für den Installationsschritt selbst brauchen Sie eine unabhängige Sicherung.
- Klären Sie die Domain. Die Lizenz wird exakt an die Hostnamen
gebunden, die auf den Website-Startseiten im Seitenbaum unter DNS eingetragen
sind. Es gibt kein Wildcard-Matching, kein Suffix-Matching und keine automatische
Gleichsetzung von
www.beispiel.deundbeispiel.de. Tragen Sie die Domain also vor der Aktivierung ein — und zwar in genau der Schreibweise, unter der die Seite erreichbar ist. - Finden Sie den Pfad zur PHP-CLI-Binary heraus. Bei Plesk ist es
derselbe Pfad, den auch der Contao Manager verwendet, typischerweise
/opt/plesk/php/8.4/bin/php. Ohne ihn laufen keine Update- und Restore-Jobs. - Entscheiden Sie über den Speicherort der Backups. Standard ist
var/updater/backup. Ein eigener absoluter Pfad ist möglich — siehe Geplante Backups.
Schreibrechte werden für diese Verzeichnisse benötigt:
| Verzeichnis | Wofür |
|---|---|
var/updater/ |
Jobs, Logs, Backups, Laufzeitkonfiguration, Lizenzzustand, Zeitplan |
vendor/ |
Composer-Update und Restore des Verzeichnisses |
public/ |
Nur wenn das Standalone-Recovery-Panel ausgeliefert werden soll |
Die Vorabprüfung kontrolliert genau diese drei Pfade und meldet fehlende Schreibrechte als „Kein Schreibzugriff: …".
Installation über den Contao Manager
- Contao Manager öffnen und anmelden.
- Bereich Entdecken öffnen. Neue Pakete werden immer dort gesucht und hinzugefügt; der Bereich Pakete daneben zeigt unter Installierte Pakete nur, was bereits vorhanden ist. Entdecken ist zugleich die Startansicht des Managers.
- Über Pakete suchen nach
vtinnovations/guardiansuchen und beim Treffer Paket hinzufügen wählen. - Änderungen anwenden. Der Contao Manager installiert das Paket und aktualisiert
den Autoloader. Das Bundle registriert sich über seinen
ContaoManager\Pluginselbst — es ist kein Eintrag in einer Bundle-Konfiguration nötig. - Bereich Systemwartung → Datenbank-Migrationen und -Backups → Datenbank prüfen; die angezeigten Datenbank-Änderungen bestätigen.
- Unter Systemwartung den Anwendungs-Cache leeren (in der Navigation auch als Cache erneuern bezeichnet).
Der Contao Manager spricht Sie in seiner Oberfläche mit du an, etwa: „Dieses Paket wird installiert, wenn du die Änderungen anwendest." Das ist die wörtliche Beschriftung des Werkzeugs und wurde hier nicht angepasst.
Installation über Composer
composer require vtinnovations/guardian
Anschließend Cache leeren und die Datenbank aktualisieren:
vendor/bin/contao-console cache:clear
vendor/bin/contao-console contao:migrate
Bei einer Managed Edition, die frisch aufgesetzt wurde, übernimmt
contao:setup die Einrichtung der Verzeichnisse und Symlinks:
vendor/bin/contao-console contao:setup
Ein späteres Update des Pakets:
composer update vtinnovations/guardian --with-dependencies
vendor/bin/contao-console cache:clear
vendor/bin/contao-console contao:migrate
Nicht per ZIP austauschen. Guardian ist ein Composer-Bundle mit
PSR-4-Autoloading. Wird das Verzeichnis unter vendor/ von Hand ersetzt,
bleibt der Autoloader auf dem alten Stand und die Klassen werden nicht gefunden.
Aktualisieren Sie ausschließlich über Composer oder den Contao Manager.
Installation überprüfen
Dass das Bundle registriert ist, zeigt der Konsolenbefehl, den es mitbringt:
vendor/bin/contao-console list guardian
In der Ausgabe muss guardian:run-job auftauchen. Erscheint der Befehl
nicht, ist das Bundle nicht geladen — dann Cache leeren und prüfen, ob das Paket
tatsächlich in composer.lock steht.
Im Backend erscheint nach dem Anmelden als Administrator:
- Im Hauptmenü unter Inhalte der Eintrag Guardian. Liegen Paket-Updates vor, steht deren Anzahl in Klammern dahinter, etwa Guardian (7).
- Unter Einstellungen der Abschnitt V-T.ONE Licence management mit dem Unterpunkt Guardian und dem Hilfetext „Guardian-Lizenz für diese Installation aktivieren, aktualisieren oder entfernen."
- Auf der Backend-Startseite eine Systemmeldung „📦 N Paket-Updates verfügbar", sobald eine Paketprüfung gelaufen ist und Updates gefunden hat.
Alle Guardian-Funktionen erfordern einen Contao-Administrator
(ROLE_ADMIN). Ein normaler Backend-Benutzer sieht den Menüpunkt nicht
nutzbar; jede Aktion der Backend-API prüft die Administratorrolle serverseitig
erneut. Das ist bewusst strenger als Contaos Standard, bei dem Backend-Routen jedem
angemeldeten Benutzer offenstehen — ein Redakteur könnte sonst ein echtes Update
auslösen oder den PHP-Binary-Pfad umschreiben.
Lizenz aktivieren
Die Lizenzverwaltung liegt zentral unter Contao → Einstellungen → Guardian Licence management. Der Abschnitt wird direkt in Contaos eigenes Einstellungsformular eingeblendet; das Bundle besitzt dafür keine eigene Route.
- Lizenzschlüssel in das Feld Lizenzschlüssel eintragen
(Format laut Platzhalter:
XXXXX-XXXXX-XXXXX-XXXXX). - Auf Lizenz prüfen & aktivieren klicken.
- Bei Erfolg erscheint: „Die Guardian-Lizenz wurde erfolgreich aktiviert."
Zwei weitere Schaltflächen stehen zur Verfügung:
| Schaltfläche | Wirkung |
|---|---|
| Lizenz prüfen & aktivieren | Prüft den eingegebenen Schlüssel gegen den Lizenzserver und legt das signierte Ergebnis lokal ab. |
| Lizenz aktualisieren | Holt den aktuellen signierten Zustand erneut. Nötig nach Ablauf der Online-Prüffrist und bei einem Schlüssel aus einer früheren Version. |
| Lizenz entfernen | Fragt per Dialog nach: „Lizenz entfernen? Lizenzierte Funktionen werden sofort deaktiviert; Backups, Jobs und Einstellungen bleiben erhalten." |
Der Hinweistext des Panels lautet: „Der Schlüssel wird als signierter Datensatz
abgelegt, nicht in der Contao-Konfiguration." Konkret landet er unter
var/updater/registration.json, zusammen mit dem Integritäts-Envelope
registration.seal und der gebundenen Domain registration.scope.
Ohne konfigurierte Domain schlägt die Aktivierung fehl. Die
Meldung lautet: „Für diese Installation ist keine Domain konfiguriert. Setze die
Domain auf einer Website-Root-Seite (oder über die Umgebungsvariable
VTINNOVATIONS_GUARDIAN_DOMAINS), bevor du eine Lizenz aktivierst." Die
Domain-Inventur speist sich aus den dns-Feldern aller
Website-Startseiten im Seitenbaum; die Umgebungsvariable ergänzt sie als
Komma-Liste für Installationen, deren Startseiten kein DNS-Feld gesetzt haben.
Ein Netzwerkfehler löscht niemals eine bestehende Lizenz. Ist der Server nicht erreichbar, meldet das Panel: „Der Lizenzserver war nicht erreichbar. Es wurde nichts geändert — eine bestehende Lizenz bleibt aktiv. Bitte später erneut versuchen."
PHP-CLI-Pfad konfigurieren
Im Backend unter Guardian → ⚙️ Einstellungen → ⚙️ PHP-CLI-Einstellungen. Der beschreibende Text lautet dort: „Updates und Restores laufen in einem Background-PHP-Prozess. Wir brauchen den absoluten Pfad zur PHP-CLI-Binary (nicht die FPM/Web-Version). … Leer lassen für Auto-Erkennung."
Guardian sucht die Binary in dieser Reihenfolge:
- Der im Backend eingetragene Pfad (
var/updater/runtime.json). - Die Umgebungsvariable
PHP_CLI_BINARYaus.env.local. - Symfonys
PhpExecutableFinder. - Die Konstante
PHP_BINARY— aber nur, wenn sie auf eine CLI-Binary zeigt. - Ableitung der CLI-Binary aus dem FPM-Pfad
(
/opt/plesk/php/8.4/sbin/php-fpm→/opt/plesk/php/8.4/bin/php). command -v phpüber die Shell.
Die Schaltfläche 🔍 Testen ruft den angegebenen Pfad mit
-v auf und prüft die Ausgabe. Ein Pfad, dessen Dateiname
-fpm oder -cgi enthält, wird sofort abgelehnt:
„This appears to be an FPM/CGI binary, not CLI. Look for the same path under
/bin/ instead of /sbin/."
Der Test prüft bewusst nicht mit file_exists(), ob die Datei
existiert. Unter Plesk verhindert open_basedir, dass PHP-FPM
/opt/plesk/php/… überhaupt sehen kann — obwohl exec()
dieselbe Binary problemlos ausführt. Aus demselben Grund zeigt die Vorschlagsliste
auf solchen Hosts alle üblichen Kandidaten statt nur die nachweislich vorhandenen.
Das erste Backup
Im Backend unter Guardian → 💾 Backup. Wählen Sie unter Backup-Inhalte die gewünschten Komponenten und klicken Sie auf 💾 Backup jetzt erstellen.
Das manuelle Backup läuft synchron. Der Bestätigungsdialog sagt
es deutlich: „Es läuft synchron — lasse diesen Tab offen, bis es fertig ist."
Anders als ein Update-Job ist dies kein Hintergrundprozess. Ist files/
ausgewählt, warnt der Dialog zusätzlich: „files/ ist ausgewählt — das kann bei
vielen Uploads mehrere Minuten dauern."
Nach Abschluss erscheint das Backup in der Liste darunter, mit Name, Größe und
enthaltenen Komponenten. Backups liegen unter
var/updater/backup/<Zeitstempel> und werden nie überschrieben.
Teil 2 — Funktionen im Detail
Die Backend-Oberfläche gliedert sich in fünf Reiter: 📊 Dashboard, 🔄 Update, 💾 Backup, 🛟 Recovery und ⚙️ Einstellungen.
Dashboard
Zeigt oben ein Lizenz-Abzeichen — „⭐ Pro-Paket aktiv", „🆓 Free-Paket aktiv" oder „🚫 Keine Lizenz" — mit der dazugehörigen Erläuterung, welche Funktionen daraus folgen.
Darunter drei Kennzahlen: Aktuelle Contao-Version, Installierte Pakete und Verfügbare Backups.
Der Block Aktueller Status zeigt den Zustand der letzten Operation:
| Anzeige | Bedeutung |
|---|---|
| ✓ Idle — keine Operation läuft | Nichts in Arbeit. Der Hinweistext ergänzt: „Die nächste Aktion (Update, Backup oder Restore), die du startest, erscheint hier." |
| ⏳ Läuft — Operation in Bearbeitung | Ein Job arbeitet gerade. |
| ✓ Letzte Operation erfolgreich | Der letzte Job ist sauber durchgelaufen. |
| ⚠️ Letzte Operation fehlgeschlagen | Der letzte Job ist gescheitert. |
Vorabprüfung (Pre-Update-Analyse)
Auf dem Dashboard, Schaltfläche 🔍 Analyse starten. Der Beschreibungstext: „Prüft die Voraussetzungen für ein Update — vollständig nur lesend, verändert nichts." Das Ergebnis wird zusammengefasst als „✅ N OK · ⚠️ N Warnungen · ❌ N Fehler".
| Prüfung | Kriterium | Meldung bei Problem |
|---|---|---|
| PHP-Version | mindestens 8.2.0 | „PHP … ist zu alt — Contao 5 benötigt mindestens PHP 8.2.0" |
| Composer | composer.phar in den üblichen Pfaden auffindbar |
„Composer wurde in den üblichen Pfaden nicht gefunden — Updates müssen ggf. anders ausgeführt werden" |
| Schreibrechte | vendor/, var/, public/ beschreibbar |
„Kein Schreibzugriff: …" |
| Speicherplatz | mindestens 500 MB frei | „Nur N MB frei — mindestens 500 MB empfohlen" |
| Composer-Pakete | keine verlassenen Pakete in vendor/composer/installed.json |
„N verlassene(s) Paket(e): …" |
| Datenbank-Konfiguration | DATABASE_URL in .env / .env.local |
„DATABASE_URL nicht in .env / .env.local gefunden — Backup muss übersprungen werden" |
| Legacy-Module | kein Inhalt unter system/modules/ |
„N Legacy-Modul(e) gefunden: … Diese verwenden das alte Contao-3-Extension-Format und sollten vor einem Upgrade auf Composer/Symfony-Bundles migriert werden." |
Die Gesamtbewertung lautet „Alles bereit — Update kann gestartet werden", „Update grundsätzlich möglich — bitte Warnungen prüfen" oder „Kritische Probleme gefunden — bitte zuerst beheben".
Paketübersicht
Ebenfalls auf dem Dashboard. 📦 Pakete laden zeigt alle installierten Composer-Pakete; 🔄 Updates prüfen fragt Packagist nach den neuesten stabilen Versionen ab — unabhängig von den aktuellen composer.json-Constraints. Die Ergebnisse werden 24 Stunden zwischengespeichert; bis dahin trägt die Anzeige den Zusatz „(gecacht — für Refresh „Updates prüfen" klicken)".
Die Tabelle hat vier Spalten: Paket, Aktuell, Verfügbar, Status. Der Status ist einer von:
| Markierung | Bedeutung |
|---|---|
| aktuell | Keine neuere Version auf Packagist. |
| Update | Eine neuere Version existiert und ist voraussichtlich installierbar. |
| ⚠ blockiert | „Update existiert, ist aber durch Constraints anderer Pakete blockiert" |
| abandoned | Das Paket wurde von seinem Autor als verlassen markiert. |
Die Oberfläche formuliert die wichtigste Einschränkung selbst: „‚Update verfügbar' bedeutet nur, dass auf Packagist eine neuere Version existiert. Ob sie tatsächlich installiert werden kann, hängt von Dependency-Constraints ab und erfordert unter Umständen, mehrere Pakete gemeinsam zu aktualisieren (z. B. bei einem Contao-Major-Upgrade)."
Manuelles Backup
Reiter 💾 Backup. Verfügbar ab der Free-Lizenz.
So erstellen Sie ein Backup
- Im Backend Inhalte → Guardian öffnen und auf den Reiter 💾 Backup wechseln.
- Unter Backup-Inhalte die Komponenten ankreuzen.
composer.json,composer.lockund die Datenbank sind immer enthalten und lassen sich nicht abwählen. Wählbar sind nurvendor/,templates/(zusammen mitcontao/templates/),files/undassets/. Welche Sie brauchen, steht in der Tabelle unten. - Auf 💾 Backup jetzt erstellen klicken.
- Den Bestätigungsdialog lesen und bestätigen. Er lautet: „Backup jetzt
erstellen? Es läuft synchron — lasse diesen Tab offen, bis es fertig ist."
Ist
files/angekreuzt, kommt hinzu: „⚠️ files/ ist ausgewählt — das kann bei vielen Uploads mehrere Minuten dauern." - Den Browser-Tab offen lassen und warten. Währenddessen steht dort „Backup wird erstellt…". Anders als ein Update ist dies kein Hintergrundjob — schließen Sie den Tab, bricht der Vorgang ab.
- Nach Abschluss erscheint die Bestätigung „Backup erstellt: <Name> · <Größe>", und das Backup steht in der Liste darunter — mit Zeitstempel, Größe und den enthaltenen Komponenten.
Welche Komponenten braucht man wirklich? Für ein Backup, aus dem
sich die Seite vollständig wiederherstellen lässt, brauchen Sie
vendor/ und files/. Ohne vendor/
müssen Sie nach einer Wiederherstellung composer install von Hand
nachziehen; ohne files/ verweist die wiederhergestellte Datenbank auf
Bilder und Dokumente, die nicht mehr da sind. Wer files/ wegen der
Größe weglässt, sollte dieses Verzeichnis getrennt sichern — etwa über das Backup
des Hosters.
| Komponente | Beschreibung laut Oberfläche | Standard |
|---|---|---|
| composer.json + composer.lock + Datenbank | „Immer enthalten — klein (wenige MB)." | immer |
| vendor/ | „Composer-Abhängigkeiten. Empfohlen. Typischerweise 100–500 MB." | an |
| templates/ + contao/templates/ | „Eigene Twig- und HTML5-Templates. Klein." | an |
| files/ | „Uploads der Nutzer — Bilder, PDFs, Videos. Oft mehrere GB. Ohne dieses Verzeichnis kann ein Rollback zu inkonsistenten DB-Referenzen und fehlenden Mediendateien führen." | aus |
| assets/ | „Generierte Bilder, Webfonts und JS/CSS-Asset-Cache. Meist wieder aufbaubar." | aus |
Ablage: var/updater/backup/<Zeitstempel>, Format
JJJJ-MM-TT_SS-MM-SS. Jedes Backup enthält eine
manifest.json mit Erstellungszeit, Contao-Version, Gesamtgröße und
Komponentenliste. Verzeichnisse werden per tar gzip-komprimiert, die
Datenbank per mysqldump; fehlen die Werkzeuge, greifen die genannten
PHP-Fallbacks.
Ein vorhandenes Backup lässt sich über Löschen entfernen. Der Dialog warnt: „Backup „…" löschen? Das kann nicht rückgängig gemacht werden."
Geplante Backups
Ebenfalls im Reiter 💾 Backup, unterhalb der Backup-Liste. Erfordert eine Pro-Lizenz; ohne sie steht dort: „🔒 Das System für geplante Backups benötigt eine gültige Pro-Lizenz. … Manuelle Backups oben bleiben verfügbar."
So richten Sie einen Zeitplan ein
- Reiter 💾 Backup öffnen und bis zum Abschnitt Geplante Backups scrollen.
- Bei 🗄️ Mini-Backup (nur DB) das Häkchen Geplante Mini-Backups aktivieren setzen. Als Einstieg sinnvoll: Häufigkeit = Täglich, Uhrzeit = eine verkehrsarme Zeit, Behalte letzte = 7 Backups.
- Bei 📦 Full-Backup ebenso verfahren — hier zusätzlich unter
In Full-Backup einschließen: die Verzeichnisse wählen.
Standard ist wöchentlich, sonntags, 02:00, 4 Backups mit
vendor/undtemplates/. - Unter Speicherort & Benachrichtigungen bei Bedarf einen
eigenen Speicherpfad eintragen (absoluter Pfad; leer lassen für
var/updater/backup). - Empfänger eintragen und mindestens Bei fehlgeschlagenem Backup benachrichtigen aktiviert lassen — sonst erfahren Sie von einem gescheiterten nächtlichen Backup nichts.
- Auf 💾 Zeitplan speichern klicken. Es erscheint „✅ Gespeichert".
- Einmal testen, bevor Sie sich darauf verlassen. Erst ✉️ Test-E-Mail jetzt senden (speichert vorher und verschickt eine Probemail), dann ▶ Mini jetzt ausführen bzw. ▶ Full jetzt ausführen. Beides läuft synchron — Tab offen lassen. Der Full-Lauf zeigt Ihnen außerdem, wie lange ein echter Durchlauf dauert.
- Unterhalb jedes Zeitplans steht danach „Letzter Lauf: …" und „Nächster Lauf: …". Vor dem ersten Lauf steht dort „Noch nie ausgeführt."
Beim Web-Cron trägt die Angabe Nächster Lauf den Zusatz „(ungefähr — feuert beim ersten Seitenaufruf nach diesem Zeitpunkt)". Das ist der Normalfall ohne eingerichteten Server-Cron und kein Fehler.
Es gibt zwei unabhängige Zeitpläne:
| Zeitplan | Inhalt | Standard |
|---|---|---|
| 🗄️ Mini-Backup (nur DB) | „Nur die Datenbank und Composer-Dateien. Schnell (wenige Sekunden)." | deaktiviert · täglich · 03:00 · 7 Backups aufbewahren |
| 📦 Full-Backup | „Datenbank + ausgewählte Verzeichnisse. Langsamer (Minuten bis zehn Minuten)." | deaktiviert · wöchentlich · sonntags · 02:00 · 4 Backups aufbewahren ·
vendor/ und templates/ an, files/ und
assets/ aus |
Als Häufigkeit stehen zwei Gruppen zur Wahl:
| Gruppe | Werte | Logik |
|---|---|---|
| 🧪 Testen (intervallbasiert) | Alle 5 Minuten · Alle 15 Minuten · Stündlich | Feuert, sobald diese Zeitspanne seit dem letzten Lauf vergangen ist — unabhängig von der Uhrzeit. |
| Produktion | Täglich · Wöchentlich · Monatlich | Feuert zur eingestellten Uhrzeit, bei wöchentlich zusätzlich am gewählten Wochentag, bei monatlich am gewählten Tag im Monat (1–28). |
Das Feld Behalte letzte N Backups begrenzt die Aufbewahrung, zulässig sind 1 bis 999.
Die Aufbewahrung räumt nur denselben Zeitplan-Typ auf. Ein Mini-Zeitplan löscht ausschließlich ältere Mini-Backups, ein Full-Zeitplan nur ältere Full-Backups. Manuell erstellte Backups sowie automatische Pre-Update- und Pre-Restore-Snapshots werden davon nie erfasst und müssen bei Bedarf selbst gelöscht werden.
Unter Speicherort & Benachrichtigungen lässt sich ein eigener
Speicherpfad angeben. Der Hilfetext lautet: „Absoluter Pfad zur
Ablage der Backups. Leer lassen für den Standard. Vermeide vendor/,
public/ und files/." Die Prüfung ist strenger als der
Hinweis: Pfade innerhalb von vendor/, public/,
web/ und files/ werden ebenso abgelehnt wie geschützte
Systemverzeichnisse (/etc, /usr, /var/log,
/boot, /root und weitere) und die zu weiten Wurzeln
/, /home und /tmp.
E-Mail-Benachrichtigungen: Empfänger, optional
Absender-E-Mail und Absender-Name (Standard
Guardian), sowie die Schalter Bei erfolgreichem Backup
benachrichtigen (Standard aus) und Bei fehlgeschlagenem Backup
benachrichtigen (Standard an). ✉️ Test-E-Mail jetzt senden
speichert zuerst und verschickt dann eine Probemail.
Zum Absender merkt die Oberfläche an: „Leer lassen, um Contaos System → Einstellungen → Administrator-E-Mail-Adresse zu nutzen. Nur überschreiben, wenn dein Hosting einen bestimmten Absender verlangt." Auf Plesk und cPanel verlangen viele Shared-Hoster, dass die From-Adresse eine echte Mailbox auf dem Server ist.
Wie geplante Backups ausgelöst werden
Guardian klinkt sich in Contaos eingebautes Cron-System ein. Beide Wege funktionieren nebeneinander und lassen sich jederzeit wechseln.
| Weg | Einrichtung | Verhalten |
|---|---|---|
| Web-Cron (Standard) | keine | Contao führt Cronjobs am Ende jedes Seitenaufrufs aus, nachdem die Antwort gesendet wurde. Der Besucher wartet nicht. Aber: „Ein für 03:00 geplantes Backup startet erst beim ersten Seitenaufruf nach 03:00. Ohne nächtlichen Traffic kann es auch erst um 08:30 laufen." |
| Echter Cron (empfohlen) | Serverseitiger Cron-Eintrag | Backups laufen pünktlich, auch ohne Besucher, und teilen keine Ressourcen mit Web-Requests. |
Der einzurichtende Befehl:
*/5 * * * * /usr/bin/php /pfad/zur/site/vendor/bin/contao-console contao:cron >/dev/null 2>&1
Anleitungen für Plesk, cPanel, DirectAdmin und SSH stehen ausklappbar direkt im Backup-Reiter. Zur Frequenz merkt die Oberfläche an: „Alle 5 Minuten ist völlig ok. Der Scheduler rate-limitet unser Backup-Job intern auf ‚stündlich' — häufigere Cron-Läufe verringern nur den Drift."
files/ in geplanten Backups ohne echten Cron ist riskant.
Beim Web-Cron läuft das Backup während eines Seitenaufrufs im Hintergrund. Dauert es
länger als ein paar Minuten und der Hoster beendet den PHP-Worker, ist das Backup
unvollständig. Testen Sie einmal mit ▶ Full jetzt ausführen, um die
Größe abzuschätzen, bevor Sie es planen.
Gegen Überschneidungen wirken zwei Mechanismen: Contao merkt sich den letzten
Ausführungszeitpunkt jedes Cronjobs, und zusätzlich verhindert ein Dateilock
(flock() auf var/updater/backup.lock), dass zwei Backups
parallel laufen. Ein Lock, das älter als 30 Minuten ist, gilt als verwaist und wird
entfernt.
Update-Jobs
Reiter 🔄 Update. Erfordert eine Pro-Lizenz. Die Oberfläche beschreibt es so: „Updates laufen als Background-Jobs in einem separaten PHP-Prozess — der Browser muss nicht offen bleiben. Fortschritt und Live-Log aktualisieren sich automatisch."
So führen Sie ein Update durch
Der vollständige Weg, in der Reihenfolge, in der er gedacht ist:
- Vorabprüfung laufen lassen. Reiter 📊 Dashboard → 🔍 Analyse starten. Stehen dort Fehler (❌), beheben Sie diese zuerst — insbesondere fehlende Schreibrechte oder zu wenig Speicherplatz lassen ein Update mitten im Lauf scheitern.
- Sehen, was überhaupt ansteht. Auf dem Dashboard 📦 Pakete laden, dann 🔄 Updates prüfen. Das Häkchen Nur Pakete mit Updates anzeigen reduziert die Liste.
- Ein eigenes Backup anlegen. Der Update-Job erstellt zwar
selbst einen Pre-Update-Snapshot, aber ein zusätzliches vollständiges Backup mit
files/kostet wenig und deckt den Fall ab, dass etwas grundsätzlich schiefgeht. Siehe Manuelles Backup. - Recovery-Panel aktivieren und testen, falls das Update riskant ist. Siehe Standalone-Recovery-Panel. Das ist der Schritt, den man im Ernstfall nicht nachholen kann.
- Dry-Run starten. Reiter 🔄 Update →
🧪 Dry-Run (sichere Simulation). Lesen Sie im Live-Log, was
Composer vorhat und ob
contao:migrateSchemaänderungen melden würde. Scheitert der Dry-Run, scheitert auch das echte Update. - Echtes Update starten. ▶ Echtes Update…
öffnet den Dialog. Dort den Update-Modus wählen,
„
vendor/in den Snapshot aufnehmen" angehakt lassen und — wenn eine Recovery-E-Mail konfiguriert ist — auch „📧 Recovery-URLs + Access-Token vor dem Update per E-Mail senden". Dann ▶ Update jetzt starten. - Warten. Die Seite geht in den Wartungsmodus. Fortschritt und Live-Log aktualisieren sich selbst; der Browser-Tab darf zu, der Job läuft im eigenen Prozess weiter.
- Ergebnis prüfen. Nach „Job beendet" die Seite im Frontend und das Backend aufrufen. Bei einem Fehlschlag steht im Job-Bereich „⚠️ Update fehlgeschlagen — Rollback verfügbar"; siehe Rollback.
- Recovery-E-Mail löschen, falls eine verschickt wurde. Sie enthält den vollständigen Access-Token und ist damit ein Vollzugriff auf die Seite.
Es gibt drei Update-Modi:
| Modus | Beschriftung | Verhalten |
|---|---|---|
| Full (Standard) | „Full — alles innerhalb der composer.json-Constraints aktualisieren" | „Aktualisiert alle Pakete auf die höchsten von composer.json erlaubten Versionen. Häufigste Wahl." |
| Konservativ | „Konservativ — stabile Releases bevorzugen" | „Wie Full, aber ohne Pre-Release-Versionen. Für strikt Patch-only in
composer.json auf ~X.Y.Z pinnen." |
| Selektiv | „Selektiv — einzelne Pakete auswählen" | „Wähle exakt aus, welche Pakete aktualisiert werden. Abhängigkeiten werden automatisch mitgezogen." |
„Konservativ" ist kein Patch-only-Modus. Technisch entspricht er
composer update --prefer-stable innerhalb der bestehenden Constraints.
Wer wirklich nur Patch-Versionen zulassen will, muss die Constraints in
composer.json selbst auf ~X.Y.Z setzen.
Jeder echte Update-Job durchläuft sechs Schritte in dieser Reihenfolge:
backup → maintenance_on → composer → cache_clear → migrate → maintenance_off
Also: Pre-Update-Snapshot, Wartungsmodus an, composer update, Cache
leeren, contao:migrate, Wartungsmodus aus.
Dry-Run
Die Schaltfläche 🧪 Dry-Run (sichere Simulation) führt die Schritte
backup → composer → cache_clear → migrate aus, wobei Composer und
contao:migrate mit --dry-run laufen. Der Bestätigungsdialog:
„Das simuliert ein Update — composer läuft mit --dry-run, contao:migrate ebenso.
Ein ECHTES Backup wird trotzdem angelegt (Sicherheitsnetz). Sonst wird nichts
verändert." Der Wartungsmodus wird dabei nicht aktiviert.
Der Dialog vor dem echten Update
▶ Echtes Update… öffnet einen Dialog mit dem Hinweis: „Dies verändert deine Live-Seite. Zuvor wird ein Pre-Update-Snapshot erstellt, damit du zurückrollen kannst." Dort werden zwei Optionen gesetzt:
| Option | Hilfetext | Standard |
|---|---|---|
„vendor/ in den Snapshot aufnehmen (empfohlen)" |
„Erlaubt einen vollständigen Rollback. Ohne dies umfasst der Rollback nur
Composer-Dateien + DB, du müsstest composer install manuell
nachziehen." |
empfohlen |
| „📧 Recovery-URLs + Access-Token vor dem Update per E-Mail senden" | „Falls etwas schiefgeht, ist diese Mail deine Rettungsleine. … Lösche die E-Mail nach erfolgreichem Update — sie enthält deinen vollständigen Access-Token." | — |
Schlägt der Versand der Recovery-E-Mail fehl, wird das Update gar nicht erst gestartet. Die Meldung lautet: „Recovery-E-Mail konnte nicht gesendet werden: … Deaktiviere die E-Mail-Option oder korrigiere die Mail-Konfiguration, bevor du das Update startest." Das ist Absicht — ohne die Rettungsleine soll kein Update laufen.
Hängende Jobs
Es kann immer nur ein Job gleichzeitig aktiv sein. Steht ein alter Job im Weg, meldet die Oberfläche: „Ein anderer Job steht im Weg:" und verweist auf die beiden Aufräum-Schaltflächen. Als stale gilt ein Job, wenn:
- er länger als 2 Minuten im Zustand queued steht — der Worker wurde nie gestartet;
- er running ist, aber der vermerkte Worker-Prozess nicht mehr existiert;
- er running ist, keine Prozess-ID hat und die Job-Datei seit 30 Minuten nicht mehr angefasst wurde.
| Schaltfläche | Wirkung |
|---|---|
| 🗑 Stale-Job aufräumen | „Das bricht den vorherigen Job ab (der offenbar gecrasht ist oder nie startete), damit du einen neuen starten kannst. Es macht KEINE bereits erledigte Arbeit rückgängig — es gibt nur den Queue-Slot frei." |
| ⛔ Abbruch erzwingen | „Nur nutzen, wenn du sicher weißt, dass der Worker wirklich hängt. Teilweise erledigte Arbeit wird NICHT zurückgenommen." Der zugrunde liegende Prozess wird dadurch nicht zwingend beendet. |
Rollback nach fehlgeschlagenem Update
Scheitert ein echtes Update, erscheint im Job-Bereich: „⚠️ Update fehlgeschlagen — Rollback verfügbar", mit der Schaltfläche ↩️ Automatischer Rollback auf Pre-Snapshot.
So rollen Sie zurück
- Im Reiter 🔄 Update auf ↩️ Automatischer Rollback auf Pre-Snapshot klicken.
- Den Bestätigungsdialog lesen und bestätigen: „Composer-Dateien, Datenbank und (falls enthalten) das vendor/-Verzeichnis werden auf den Stand vor dem fehlgeschlagenen Update zurückgesetzt. Die Seite geht während des Rollbacks in den Wartungsmodus."
- Der Rollback läuft als eigener Job. Im Live-Log erscheint „Rollback gestartet. Verfolge den Live-Log unten."
- Nach Abschluss den Wartungsmodus prüfen und die Seite im Frontend aufrufen.
Dieser Weg ist an einen bestimmten fehlgeschlagenen Job gebunden: Guardian
schlägt dessen Pre-Update-Snapshot im Job-Archiv nach und stellt ihn wieder her. Eine
Auswahl, welche Komponenten zurückgesetzt werden, gibt es hier bewusst nicht
— der Rollback stellt alle im Snapshot enthaltenen Komponenten
wieder her (Composer-Dateien, Datenbank, vendor/, templates/,
files/, assets/) und schaltet dabei immer den Wartungsmodus
ein.
Der Restore ist best-effort, nicht transaktional. Die Komponenten werden nacheinander wiederhergestellt. Bricht ein Schritt ab, wird kein bereits abgeschlossener Schritt automatisch zurückgenommen. Der Rollback selbst ist zudem ein bewusster manueller Klick, kein automatischer Vorgang.
Existiert kein Snapshot zu dem Job, meldet die API: „Kein Pre-Update-Snapshot zu diesem Job vorhanden. Manueller Restore erforderlich."
Für den Fall, dass der Button nicht mehr erreichbar ist, verweist die Oberfläche selbst weiter: „Wenn dieser Button nicht funktioniert (z. B. weil das fehlgeschlagene Update Contao selbst zerlegt hat), nutze das Standalone-Recovery-Panel aus dem Recovery-Tab — es funktioniert ohne Contao oder Symfony."
Aus einem Backup wiederherstellen
Das Contao-Backend bietet keinen Weg, ein beliebiges Backup zurückzuspielen. Die einzige Wiederherstellung im Backend ist der Rollback auf den Pre-Update-Snapshot eines fehlgeschlagenen Jobs. Wollen Sie ein anderes Backup einspielen — etwa das nächtliche Mini-Backup von vorgestern —, führt der Weg ausschließlich über das Standalone-Recovery-Panel.
Das ist Absicht und wird im Recovery-Reiter begründet: „Restore ist eine
Out-of-Band-Operation — bewusst wird sie nicht aus diesem Contao-Backend heraus
ausgelöst." Zum einen braucht man einen Restore meistens genau dann, wenn Contao
nicht mehr läuft. Zum anderen ist es gefährlich, vendor/
zurückzuspielen, während Symfony aus demselben Verzeichnis liest — das Backend würde
mitten im Vorgang abstürzen.
Daraus folgt eine Konsequenz, die man vor dem Ernstfall kennen sollte:
Ohne Pro-Lizenz und ohne aktiviertes Recovery-Panel gibt es keinen Weg,
ein Backup über Guardian zurückzuspielen. Mit einer Free-Lizenz können Sie
Backups erstellen, aber nicht einspielen. Die Archive unter
var/updater/backup/<Zeitstempel>/ sind reguläre
tar-/gzip-Dateien plus ein SQL-Dump und lassen sich
selbstverständlich von Hand über SSH entpacken und importieren — komfortabel ist
das nicht.
Der Ablauf im Überblick
| Ausgangslage | Weg |
|---|---|
| Update ist gerade fehlgeschlagen, Backend läuft noch | Rollback-Schaltfläche im Update-Reiter — ein Klick, stellt den Pre-Update-Snapshot vollständig wieder her. |
| Contao bootet nicht mehr | Standalone-Recovery-Panel im Browser öffnen. Setzt voraus, dass es vorher aktiviert wurde. |
| Backend läuft, Sie wollen ein älteres Backup einspielen | Ebenfalls über das Standalone-Recovery-Panel — es ist auch bei intaktem Contao erreichbar und der einzige Weg mit Komponentenauswahl. |
| Panel wurde nie aktiviert und Contao ist kaputt | Kein Guardian-Weg mehr. Es bleibt die manuelle Wiederherstellung über SSH oder das Backup des Hosters. |
Standalone-Recovery-Panel
Reiter 🛟 Recovery. Erfordert eine Pro-Lizenz.
Das Panel ist eine einzelne PHP-Datei ohne Framework-Abhängigkeiten, die der Webserver direkt ausliefert. Sie kann Backups auflisten, Komponenten selektiv wiederherstellen — inklusive Datenbank-Import — und den Wartungsmodus steuern.
Die Begründung, warum Restore bewusst nicht aus dem Contao-Backend heraus läuft,
steht im Reiter selbst: „Wenn Contao läuft, brauchst du meistens keinen Restore.
Wenn du einen brauchst, ist Contao wahrscheinlich kaputt." Und:
„vendor/ wiederherzustellen, während Symfony aus demselben Verzeichnis
liest, ist gefährlich — das Backend würde mitten im Restore abstürzen."
Auslieferung aktivieren
Die Auslieferung ist opt-in. In .env.local:
VTINNOVATIONS_GUARDIAN_DEPLOY_RECOVERY_PANEL=1
Danach Cache leeren. Beim nächsten Kernel-Boot kopiert das Bundle die Datei nach
public/. Akzeptierte Werte für das Flag sind 1,
true, yes und on.
Zwei Bedingungen müssen gemeinsam erfüllt sein: das Flag und eine gültige Pro-Berechtigung. Fällt eine davon weg, entfernt das Bundle die Datei beim nächsten Boot selbsttätig wieder aus dem Webroot — das Abschalten beseitigt die Angriffsfläche also tatsächlich, statt eine verwaiste Datei liegen zu lassen. Die Berechtigungsprüfung läuft dabei unabhängig von den Controllern direkt beim Boot.
Empfehlung des Bundles: Panel nur für die Dauer riskanter Updates aktivieren und zusätzlich auf Webserver-Ebene schützen (IP-Allowlist oder HTTP-Auth). Der Token ist die letzte Verteidigungslinie, nicht die einzige. Testen Sie den Zugriff vor einem Update — im Ernstfall lässt sich das nicht nachholen.
Dateiname
Standard ist _updater-recovery.php. Unter
🛟 Recovery-Panel-Dateiname lässt sich ein eigener Name setzen:
„Ein eigener Dateiname erschwert das Auffinden durch Scanner (Security through
Obscurity zusätzlich zur Token-Authentifizierung). Muss auf .php enden,
nur Buchstaben/Zahlen/._-, max. 60 Zeichen." Beim Umbenennen wird
die vorherige Datei beim nächsten Boot entfernt.
Access-Token
Das Panel nutzt HTTP Basic Auth: „Der Benutzername ist beliebig; das Passwort
ist der hier verwaltete Access-Token." Alternativ wird ein
Authorization: Bearer-Header akzeptiert. Ein Token im
URL-Query-String wird bewusst nicht akzeptiert — er würde in
Server-Logs und Referer-Headern landen.
Zwei Token-Quellen, in dieser Reihenfolge:
VTINNOVATIONS_GUARDIAN_TOKENin.env.local— hat Vorrang.- Eine automatisch erzeugte Datei
var/updater/access.token.
Stammt der Token aus der Umgebung, zeigt die Oberfläche das Abzeichen
„aus .env", sonst „auto-generiert". Bei einem Token aus
.env ist die Rotation im Backend gesperrt: „Der Token stammt aus .env.
Bearbeite VTINNOVATIONS_GUARDIAN_TOKEN in .env.local, um ihn zu rotieren."
Der Token wird nur einmal vollständig angezeigt. Im Normalfall zeigt das Backend eine maskierte Vorschau. Um den vollständigen Token zu erhalten, klicken Sie auf 🔄 Token rotieren, um eine neue Kopie zu erhalten — der alte Token wird dabei sofort ungültig, der neue genau einmal angezeigt. Speichern Sie URL und Token an diesem Punkt außerhalb von Contao: „Wenn Contao ausfällt, kannst du sie von dieser Seite nicht mehr kopieren."
So stellen Sie damit wieder her
- Panel öffnen.
https://ihre-domain.de/_updater-recovery.phpim Browser aufrufen — bzw. den selbst gesetzten Dateinamen. - Anmelden. Der Browser zeigt einen Basic-Auth-Dialog. Tragen Sie einen beliebigen Benutzernamen ein und als Passwort den Access-Token.
- Lage prüfen. Unter System diagnostics zeigt das Panel,
was es auf dem Server vorfindet — etwa ob
mysqlundtarverfügbar sind. Unter Available backups stehen alle Backups mit ihrem Manifest. - Backup wählen. Im Abschnitt Restore from backup das gewünschte Backup auswählen.
- Komponenten ankreuzen. Wählbar sind sechs:
composer,database,vendor,templates,filesundassets. Anders als beim Rollback im Backend entscheiden Sie hier selbst, was zurückgespielt wird. - Wartungsmodus. Er ist standardmäßig eingeschaltet und sollte es
bleiben, sobald
vendor/oder die Datenbank betroffen sind. Besucher sehen währenddessen die Seite „Site is being restored". - Wiederherstellung starten und im Live log mitlesen. Das Panel hebt Zeit- und Speicherlimit selbst an und protokolliert jeden Schritt.
- Nachkontrolle. Frontend und Backend aufrufen. Wurde
vendor/zurückgespielt, anschließend den Cache leeren.
Die Oberfläche des Panels ist englisch — es ist bewusst eine abhängigkeitsfreie Einzeldatei und bindet Contaos Übersetzungen nicht ein. Die Abschnitte heißen System diagnostics, Available backups, Restore from backup und Live log.
Neben der Wiederherstellung kann das Panel Backups auflisten, deren Manifest anzeigen, ein Backup löschen und den Wartungsmodus separat schalten.
Ein Brute-Force-Schutz sperrt nach 8 Fehlversuchen je IP-Adresse innerhalb von
15 Minuten für 15 Minuten. Hinter einem gemeinsamen Proxy oder CDN mit fester
Absender-IP teilen sich alle Clients dasselbe Kontingent. Vor dem Entpacken prüft das
Panel jeden Archiveintrag — keine absoluten Pfade, kein .., kein
Verlassen des Zielverzeichnisses.
Eine Einschränkung: Die Komponente templates umfasst
im Panel immer templates/ und contao/templates/
zusammen — beide lassen sich hier nicht getrennt wiederherstellen.
Lizenzzustände
Guardian kennt drei Stufen — Trial, Free und Pro — und jede davon erfordert einen aktivierten, signierten Schlüssel. Es gibt keinen anonymen Free-Modus und keine Testphase, die sich lokal starten ließe.
| Funktion | Ohne Lizenz | Free | Pro / Trial |
|---|---|---|---|
| Dashboard und Einstellungen | ✓ | ✓ | ✓ |
| Vorabprüfung und Paketübersicht | ✓ | ✓ | ✓ |
| Manuelles Backup | — | ✓ | ✓ |
| Update-Jobs (Composer) | — | — | ✓ |
| Restore / Recovery | — | — | ✓ |
| Geplante Backups (Mini + Full) | — | — | ✓ |
| Standalone-Recovery-Panel | — | — | ✓ |
| Recovery-E-Mail-Benachrichtigungen | — | — | ✓ |
Trial und Pro sind hinsichtlich der freigeschalteten Funktionen identisch; der Unterschied liegt allein in der Befristung des signierten Datensatzes.
Die Meldungen, die das Lizenz-Panel je nach Zustand anzeigt:
| Zustand | Meldung |
|---|---|
| Pro aktiv | „Pro-Lizenz aktiv. Alle Funktionen freigeschaltet." |
| Trial aktiv | „Trial-Lizenz aktiv. Alle Funktionen freigeschaltet, bis die Testphase endet." |
| Free aktiv | „Free-Lizenz aktiv. Nur manuelles Backup." |
| Pro abgelaufen, Fallback erlaubt | „Pro-Lizenz abgelaufen. Läuft im Free-Funktionsumfang (nur manuelles Backup)." |
| Abgelaufen, kein Fallback | „Lizenz abgelaufen. Alle lizenzierten Funktionen sind deaktiviert." |
| Noch nicht gültig | „Lizenz ist noch nicht gültig. Alle lizenzierten Funktionen sind deaktiviert." |
| Domain passt nicht | „Lizenz ist für keine der auf dieser Installation konfigurierten Domains gültig." |
| Vom Aussteller zurückgezogen | „Lizenz ist nicht mehr gültig. Klicke auf „Lizenz aktualisieren", oder kontaktiere V&T Innovations." |
| Online-Prüffrist überschritten | „Lizenz muss online neu geprüft werden und war nicht rechtzeitig erreichbar. Klicke auf „Lizenz aktualisieren", sobald wieder eine Verbindung besteht." |
| Keine Lizenz | „Keine Lizenz aktiviert. Nur Dashboard und Einstellungen sind verfügbar." |
sodium fehlt |
„Guardian kann auf diesem Server keine Lizenzen prüfen: die PHP-Sodium-Erweiterung fehlt." |
Die Lizenz wird exakt an Hostnamen gebunden — kein Wildcard, kein Suffix-Matching,
keine automatische Gleichsetzung von www-Variante und Apex-Domain. Der
signierte Datensatz trägt eine Online-Prüffrist; läuft sie ab und bleibt der Server
unerreichbar, greift zunächst ein signiertes Kulanzfenster und danach fallen die
geschützten Funktionen aus (fail closed). Ein stündlicher Cronjob versucht die
Auffrischung rechtzeitig — er beginnt sechs Stunden vor der Frist und wiederholt es
frühestens alle 30 Minuten.
Teil 3 — Für Entwickler
Konsolenbefehl
Das Bundle registriert genau einen Befehl:
vendor/bin/contao-console guardian:run-job <job-id>
| Eigenschaft | Wert |
|---|---|
| Name | guardian:run-job |
| Beschreibung | „Executes a queued update job (CLI worker, internal use)" |
| Argument | job-id (erforderlich) — ID des auszuführenden Jobs |
| Optionen | keine |
Der Befehl ist der Worker, den das Backend als eigenständigen Prozess startet. Er
lässt sich zu Diagnosezwecken auch manuell aufrufen, erwartet dann aber genau die ID
des aktuell in var/updater/job.json hinterlegten Jobs — andernfalls bricht
er mit „Job ID mismatch" ab. Er hebt sein eigenes Zeitlimit auf, setzt das
Speicherlimit auf 512 MB und prüft die Lizenzberechtigung eigenständig noch einmal:
ein Restore-Job verlangt die Restore-Berechtigung, jeder andere die
Update-Berechtigung. Fehlt sie, endet er mit „This operation requires a valid
Guardian licence."
Routen
Alle Backend-Routen tragen das Präfix %contao.backend.route_prefix%/updater
(standardmäßig /contao/updater), laufen im Scope backend und
verlangen bis auf die Einstiegsseite POST. Jede Aktion prüft
ROLE_ADMIN serverseitig.
| Pfad (nach dem Präfix) | Routenname | Methode |
|---|---|---|
/updater | …\Controller\BackendController | GET |
/updater/analyse | vtinnovations_guardian_analyse | POST |
/updater/packages | vtinnovations_guardian_packages | POST |
/updater/backup/create | vtinnovations_guardian_backup_create | POST |
/updater/backup/list | vtinnovations_guardian_backup_list | POST |
/updater/backup/delete | vtinnovations_guardian_backup_delete | POST |
/updater/job/start | vtinnovations_guardian_job_start | POST |
/updater/job/status | vtinnovations_guardian_job_status | POST |
/updater/job/log | vtinnovations_guardian_job_log | POST |
/updater/job/archive | vtinnovations_guardian_job_archive | POST |
/updater/job/rollback | vtinnovations_guardian_job_rollback | POST |
/updater/job/clear-stale | vtinnovations_guardian_job_clear_stale | POST |
/updater/schedule/get | vtinnovations_guardian_schedule_get | POST |
/updater/schedule/save | vtinnovations_guardian_schedule_save | POST |
/updater/schedule/run | vtinnovations_guardian_schedule_run | POST |
/updater/schedule/test-email | vtinnovations_guardian_schedule_test_email | POST |
/updater/runtime/get | vtinnovations_guardian_runtime_get | POST |
/updater/runtime/save | vtinnovations_guardian_runtime_save | POST |
/updater/runtime/test | vtinnovations_guardian_runtime_test | POST |
/updater/runtime/test-recovery-email | vtinnovations_guardian_runtime_test_recovery_email | POST |
/updater/panel/get | vtinnovations_guardian_panel_get | POST |
/updater/panel/rotate | vtinnovations_guardian_panel_rotate | POST |
Eine Route liegt bewusst außerhalb des Backends:
| Pfad | Routenname | Zweck |
|---|---|---|
/rest/api/v1/guardian-license-updater |
vtinnovations_guardian_registry_hook |
Server-zu-Server-Zustellung neuer Lizenzpakete. Nicht durch den
Backend-Login geschützt, sondern kryptografisch authentifiziert: signiert werden
Methode, Pfad, Request-ID, Zeitstempel, Nonce und Body-Hash. Wiedereinspielungen
wehrt ein Replay-Ledger unter var/updater/exchange.journal ab. |
Schreibende Backend-Requests unterliegen zusätzlich einem
Same-Origin-CSRF-Check (Origin, mit Referer-Fallback). Die
Updater-Route ist davon ausgenommen, da sie signaturbasiert authentifiziert wird.
Dateien unter var/updater/
Guardian legt keine eigenen Datenbanktabellen an. Der gesamte Zustand liegt im Dateisystem:
| Pfad | Inhalt |
|---|---|
backup/<Zeitstempel>/ | Backup-Archive und manifest.json |
backup.lock | flock()-Sperre gegen parallele Backups |
job.json | Der eine aktive Job |
job.log | Live-Log des aktiven Jobs |
jobs/ | Archiv abgeschlossener Jobs |
status.json | Zustand der letzten Operation (Dashboard) |
outdated.json | Gecachtes Ergebnis der Packagist-Abfrage (24 h) |
runtime.json | PHP-CLI-Pfad, Composer-Phar, Recovery-E-Mail, Panel-Dateiname |
schedule.json | Konfiguration der geplanten Backups |
schedule_state.json | Letzter Lauf je Zeitplan-Typ |
access.token | Token des Recovery-Panels (nur wenn nicht über .env gesetzt) |
registration.json / .seal / .scope | Lizenzdatensatz, Integritäts-Envelope, gebundene Domain |
registration.tomb / .tomb.seal | Signierter Grabstein: höchste akzeptierte negative Version |
lease.attempt | Zeitstempel des letzten Auffrischungsversuchs |
exchange.journal | Replay-Ledger für server-initiierte Lizenzupdates |
Das Zurückspielen einer alten registration.json aus einem
Backup hebt einen Widerruf nicht auf. Ein signierter negativer Zustand wird
als selbst-authentifizierender Grabstein festgehalten; die höchste jemals akzeptierte
Version überlebt jede Dateiwiederherstellung. Jede Veränderung an
registration.json, .seal oder .scope führt
beim nächsten Lesen zu „unlizenziert" — es gibt keinen Lesepfad an der
Signaturprüfung vorbei.
Cronjobs
Zwei Cronjobs registrieren sich über Contaos AsCronJob-Attribut:
| Klasse | Intervall | Aufgabe |
|---|---|---|
Cron\BackupCron |
minutely |
Prüft, ob ein geplantes Backup fällig ist, und führt es gegebenenfalls aus. Das Minutenintervall erlaubt die Test-Frequenzen (5/15 Minuten); die Fälligkeitsprüfung selbst ist praktisch kostenlos. |
Cron\LeaseRefreshCron |
hourly |
Frischt den signierten Lizenzzustand auf, sobald die Online-Prüffrist näher rückt. Beginnt 6 Stunden vor der Frist, wiederholt frühestens alle 30 Minuten. Ein Netzwerkfehler verändert nichts. |
Im Web-Scope führt Contao beide in kernel.terminate aus, also nachdem
die Antwort gesendet wurde. BackupCron hebt dafür Zeit- und Speicherlimit
an, setzt ignore_user_abort(true) und leert die Ausgabepuffer.
Umgebungsvariablen
| Variable | Wirkung |
|---|---|
VTINNOVATIONS_GUARDIAN_DEPLOY_RECOVERY_PANEL |
Schaltet die Auslieferung des Standalone-Recovery-Panels frei. Akzeptiert
1, true, yes, on. Ohne sie
wird eine vorhandene Panel-Datei beim nächsten Boot entfernt. |
VTINNOVATIONS_GUARDIAN_TOKEN |
Fixiert den Access-Token des Recovery-Panels. Hat Vorrang vor
var/updater/access.token; die Rotation im Backend ist dann gesperrt. |
VTINNOVATIONS_GUARDIAN_DOMAINS |
Komma-getrennte Liste zusätzlicher Domains für die Lizenzbindung. Gedacht für Installationen, deren Website-Startseiten kein DNS-Feld gesetzt haben. |
PHP_CLI_BINARY |
Absoluter Pfad zur PHP-CLI-Binary. Greift, wenn im Backend nichts eingetragen ist, und geht der Auto-Erkennung vor. |
Achtung, abweichender Variablenname in einer Fehlermeldung.
Schlägt der Start des Workers fehl, nennt die Meldung
VTINNOVATIONS_GUARDIAN_PHP_BINARY. Diese Variable wird vom Code
nicht gelesen. Die wirksame Variable heißt PHP_CLI_BINARY;
der bevorzugte Weg bleibt ohnehin das Feld PHP-Binary unter
PHP-CLI-Einstellungen.
Protokollierung
Wichtige Ereignisse aus Updates und geplanten Backups schreibt Guardian zusätzlich
in Contaos Systemlog. Zu finden unter System → Systemlog, filterbar
über die Aktion VTINNOVATIONS_GUARDIAN. Die Oberfläche begründet es so:
„So kannst du auch nachträglich nachvollziehen, was passiert ist, wenn das
Live-Log hier weg ist."
Zu unterscheiden sind zwei Protokolle:
| Protokoll | Umfang | Verwendung |
|---|---|---|
Live-Log (var/updater/job.log) |
Jede Ausgabezeile jedes Schritts | Die laufende Anzeige im Backend während eines Jobs |
Systemlog (tl_log) |
Zusammenfassung der wichtigen Ereignisse | Nachträgliche Fehlersuche über Contaos reguläre Oberfläche |
Lizenzschlüssel, Payloads, Digests, Signaturen und Nonces werden nie protokolliert und erscheinen nicht in Browser-Antworten. Das Paket sichert das über eine eigene Testsuite strukturell ab.
Keine Erweiterungspunkte
Guardian ist bewusst geschlossen gebaut. Folgendes existiert nicht und sollte nicht erwartet werden:
- Keine eigenen Hooks oder Events. Das Bundle hört auf
Contaos
getSystemMessages-Hook und auf die Kernel-Events für Backend-Menü, CSRF-Prüfung und Nutzungssignal — es sendet aber keine eigenen Events, in die sich andere Pakete einklinken könnten. - Keine Bundle-Konfiguration. Die DI-Extension lädt ausschließlich
die eigene
services.yaml; es gibt keinenguardian:-Abschnitt inconfig.yaml. Alles Konfigurierbare liegt im Backend bzw. invar/updater/runtime.json. - Keine Datenbanktabellen und keine Models. Der gesamte Zustand
liegt unter
var/updater/. - Keine eigene Route für die Lizenzverwaltung. Das Panel
rendert innerhalb von Contaos eigenem
tl_settings-Formular; die Schaltflächen tragen bewusst keinformaction. - Kein Frontend-Modul und kein Content-Element. Guardian ist reines Backend-Werkzeug.
- Der Major-Upgrade-Modus ist deaktiviert. Der Code für die Pipeline ist im Paket vorhanden, aber jede Anfrage dafür wird abgelehnt: „Der Major-Upgrade-Modus ist in dieser Version deaktiviert." Weder Oberfläche noch Route bieten ihn an.
Zu umgehen sind die Lizenz-Gates ebenfalls nicht durch das Ausschalten der Oberfläche: Sie werden serverseitig an jeder Funktionsgrenze einzeln durchgesetzt — im Controller, im CLI-Worker, im Cron-Runner, beim Mailversand und beim Panel-Deployment im Bundle-Boot.
Fehlerbehebung
| Symptom | Ursache und Prüfung |
|---|---|
| Menüpunkt Guardian erscheint nicht unter „Inhalte" | Sie sind nicht als Administrator angemeldet, oder das Bundle ist nicht
geladen. Prüfen mit
vendor/bin/contao-console list guardian — erscheint
guardian:run-job nicht, Cache leeren und
composer.lock prüfen. |
| „❌ Worker konnte nicht gestartet werden" | Die PHP-CLI-Binary wurde nicht gefunden oder ist nicht ausführbar. Der Hinweis der Oberfläche: „Öffne unten den Bereich ‚PHP-CLI-Einstellungen' und trage den korrekten Pfad zur PHP-CLI-Binary ein (z. B. /opt/plesk/php/8.4/bin/php bei Plesk), dann erneut versuchen." Siehe PHP-CLI-Pfad konfigurieren. |
| „This appears to be an FPM/CGI binary, not CLI." | Der eingetragene Pfad zeigt auf die Web-Variante. Dieselbe Version liegt
meist unter /bin/ statt /sbin/, ohne
-fpm-Suffix. |
| „Cannot test: exec() is in disable_functions." | Der Hoster hat exec() gesperrt. Der Test der Binary ist dann
nicht möglich; der Worker-Start ebenfalls nicht. Hier hilft nur der Hoster. |
| Lizenz lässt sich nicht aktivieren: „Für diese Installation ist keine Domain konfiguriert." | Keine Website-Startseite im Seitenbaum hat ein dns-Feld gesetzt.
Domain dort eintragen oder VTINNOVATIONS_GUARDIAN_DOMAINS in
.env.local setzen. |
| „Lizenz ist für keine der auf dieser Installation konfigurierten Domains gültig." | Schreibweise prüfen. www.beispiel.de und
beispiel.de sind zwei verschiedene Hosts; es gibt kein
Wildcard- oder Suffix-Matching. |
| „Guardian kann auf diesem Server keine Lizenzen prüfen: die PHP-Sodium-Erweiterung fehlt." | ext-sodium ist nicht installiert. Ohne sie bleibt die
Installation unlizenziert — das ist keine Einstellung, sondern eine harte
Voraussetzung. |
| „Guardian hat einen Lizenzschlüssel aus einer früheren Version gefunden…" | Ein Schlüssel aus einer Version vor den signierten Datensätzen. Auf Lizenz aktualisieren klicken, um ihn neu zu authentifizieren. |
| „Der Lizenzserver war nicht erreichbar." | Netzwerk oder Firewall. Es wurde nichts geändert, eine bestehende Lizenz bleibt aktiv. Später erneut versuchen. |
| Datenbank fehlt im Backup / „DATABASE_URL nicht in .env / .env.local gefunden" | Ohne DATABASE_URL wird nur der Datenbankteil übersprungen; das
übrige Backup läuft durch. Die
Vorabprüfung meldet es als Warnung. |
| Geplantes Backup läuft nicht zur eingestellten Zeit | Beim Web-Cron feuert es erst beim ersten Seitenaufruf nach dem Zeitpunkt.
Ohne nächtlichen Traffic verschiebt sich das. Abhilfe: echter Server-Cron auf
contao:cron, siehe
Geplante Backups. |
Geplantes Backup mit files/ bleibt unvollständig |
Beim Web-Cron beendet der Hoster den PHP-Worker, bevor das Archiv fertig ist. Erst mit ▶ Full jetzt ausführen die Dauer messen, dann echten Cron einrichten. |
| Speicherpfad wird abgelehnt | „Speicherpfad ist ungültig: …" — der Pfad ist nicht absolut, liegt in
einem geschützten Systemverzeichnis, innerhalb von vendor/,
public/, web/ oder files/, oder er ist
nicht beschreibbar. |
| „Ein anderer Job steht im Weg:" | Ein vorheriger Job ist noch aktiv oder hängt. Erst 🗑 Stale-Job aufräumen versuchen; ⛔ Abbruch erzwingen nur, wenn sicher ist, dass der Worker nicht mehr reagiert. |
| Update startet nicht, „❌ Recovery-E-Mail konnte nicht gesendet werden" | Absichtlich. Entweder die Mail-Konfiguration unter Einstellungen → Recovery-E-Mail korrigieren, oder das Häkchen „Recovery-URLs per E-Mail senden" im Update-Dialog für diesen Lauf entfernen. |
| „Symfony Mailer ist nicht verfügbar." | MAILER_DSN ist in .env.local nicht gesetzt. Ohne
sie funktionieren weder Recovery- noch Backup-Benachrichtigungen. |
| Test-Mail schlägt fehl, obwohl Contao sonst Mails versendet | Viele Shared-Hoster verlangen, dass die Absenderadresse eine echte Mailbox auf dem Server ist. Absender auf eine in Plesk/cPanel angelegte Adresse setzen. |
| Es gibt keine Schaltfläche, um ein vorhandenes Backup einzuspielen | Richtig — das Backend bietet nur den Rollback auf den Snapshot eines fehlgeschlagenen Update-Jobs. Jede andere Wiederherstellung läuft über das Standalone-Recovery-Panel. Siehe Aus einem Backup wiederherstellen. |
| „Unbekannter Job-Typ: restore" | Ein Restore lässt sich nicht über den regulären Job-Start auslösen; die
Backend-API akzeptiert dort nur dry_run und update.
Nutzen Sie die Rollback-Schaltfläche oder das Recovery-Panel. |
| Backup ist da, aber ohne Pro-Lizenz nicht einspielbar | Wiederherstellung und Recovery-Panel sind Pro-Funktionen. Free deckt nur
das Erstellen von Backups ab. Die Archive selbst sind reguläre
tar-/gzip-Dateien plus SQL-Dump und lassen sich über
SSH auch von Hand einspielen. |
| Standalone-Recovery-Panel liefert 404 | Die Datei wurde nicht ausgeliefert. Drei Bedingungen prüfen:
VTINNOVATIONS_GUARDIAN_DEPLOY_RECOVERY_PANEL=1 gesetzt, gültige
Pro-Lizenz vorhanden, und danach der Cache geleert — die Datei entsteht erst beim
nächsten Kernel-Boot. |
| Panel fragt nicht nach Zugangsdaten oder weist den Token ab | Der Token gehört als Passwort in den Basic-Auth-Dialog, der Benutzername ist beliebig. Ein Token im Query-String wird bewusst nicht akzeptiert. Nach 8 Fehlversuchen je IP innerhalb von 15 Minuten greift eine 15-minütige Sperre. |
| Der angezeigte Token funktioniert nicht | Angezeigt wird nur eine maskierte Vorschau. Den vollständigen Token gibt es ausschließlich einmalig nach Token rotieren — dabei wird der alte sofort ungültig. |
| Paketübersicht zeigt veraltete Zahlen | Die Packagist-Abfrage wird 24 Stunden gecacht. 🔄 Updates prüfen erzwingt eine frische Abfrage. |
| Angezeigtes Update lässt sich nicht installieren, Markierung ⚠ blockiert | Die neuere Version existiert, ist aber durch Constraints anderer Pakete
gesperrt. Typischerweise müssen mehrere Pakete gemeinsam aktualisiert werden;
bei Contao zieht meist ein Update von contao/manager-bundle alles
nach. |
Bekannte Einschränkungen
- Restore und Rollback sind best-effort, nicht transaktional. Komponenten werden nacheinander wiederhergestellt; bricht ein Schritt ab, wird kein bereits abgeschlossener Schritt automatisch zurückgenommen.
- Der Rollback nach einem fehlgeschlagenen Update ist ein manueller Klick, kein automatischer Vorgang.
- „Konservativ" ist kein echter Patch-only-Modus — technisch
composer update --prefer-stableinnerhalb der bestehenden Constraints. - Der Wartungsmodus wird beim Restore nur dann automatisch aktiviert,
wenn
vendor/zu den wiederherzustellenden Komponenten gehört. - Die Aufbewahrung greift nur je Zeitplan-Typ. Manuelle Backups und Pre-Update-/Pre-Restore-Snapshots werden nie automatisch gelöscht.
- „Abbruch erzwingen" beendet den Hintergrundprozess nicht zwingend — es markiert den Job als abgebrochen und gibt den Queue-Slot frei.
- Im Contao-Backend lässt sich kein beliebiges Backup zurückspielen. Dort gibt es nur den Rollback auf den Pre-Update-Snapshot eines fehlgeschlagenen Jobs — ohne Komponentenauswahl, immer vollständig. Jede andere Wiederherstellung läuft über das Standalone-Recovery-Panel, das dafür vorher aktiviert worden sein muss.
- Das Standalone-Panel kann
contao/templates/nicht getrennt vontemplates/wiederherstellen — die Komponentetemplatesumfasst dort immer beide Verzeichnisse. - Das manuelle Backup läuft synchron im Browser-Request, nicht als
Hintergrundjob. Bei großen
files/-Verzeichnissen kann es das PHP-Zeitlimit reißen. - Mehrknoten-Betrieb ohne gemeinsames
var/wird nicht unterstützt. Lizenzzustand, Job-Ablage und Replay-Ledger liegen im Dateisystem und setzen einen gemeinsamen, transaktionalen Speicher voraus. - Der Major-Upgrade-Modus ist in dieser Version deaktiviert. Sprünge über Major-Versionen hinweg — etwa Contao 5.3 auf 5.7 — müssen außerhalb von Guardian durchgeführt werden.
- Eine Lizenz gilt genau für die signierten Hostnamen. Umzug auf eine neue Domain erfordert eine Aktualisierung durch V&T Innovations.
Deinstallation
- Lizenz entfernen unter Contao → Einstellungen → Guardian Licence management → Lizenz entfernen. Das gibt die Bindung an diese Installation frei, bevor das Paket verschwindet.
- Auslieferung des Recovery-Panels abschalten: die Zeile
VTINNOVATIONS_GUARDIAN_DEPLOY_RECOVERY_PANEL=1aus.env.localentfernen und den Cache leeren. Beim nächsten Boot entfernt das Bundle die Datei auspublic/selbsttätig. Führen Sie diesen Schritt vor dem Entfernen des Pakets aus — danach räumt niemand mehr auf und die Datei bliebe im Webroot liegen. - Serverseitigen Cron-Eintrag entfernen, falls einer nur für
Guardian eingerichtet wurde. Nutzen andere Erweiterungen
contao:cron, lassen Sie ihn stehen. - Paket entfernen — im Contao Manager unter Pakete
bei
vtinnovations/guardian, oder über Composer:composer remove vtinnovations/guardian vendor/bin/contao-console cache:clear - Arbeitsdaten prüfen. Das Verzeichnis
var/updater/bleibt erhalten. Es enthält Ihre Backups. Löschen Sie es erst, wenn Sie die darin liegenden Sicherungen nicht mehr benötigen oder an einen anderen Ort kopiert haben.
Prüfen Sie nach der Deinstallation, ob
public/_updater-recovery.php — oder Ihr eigener Dateiname — wirklich
verschwunden ist. Wurde das Paket entfernt, ohne vorher das Flag
abzuschalten und den Cache zu leeren, bleibt die Datei liegen und ist weiterhin über
den Webserver erreichbar. In dem Fall von Hand löschen.
Weitere Spuren hinterlässt Guardian nicht: Es gibt keine eigenen Datenbanktabellen.
Die Einträge im Contao-Systemlog mit der Aktion VTINNOVATIONS_GUARDIAN
bleiben als Historie bestehen und lassen sich über Contaos reguläre Log-Verwaltung
entfernen.
