Laravel-Wartung: Updates, Testing und langfristiger Betrieb

Laravel-Anwendungen erfordern kontinuierliche Pflege. Framework-Releases folgen einem festen Rhythmus, Composer-Abhängigkeiten können Sicherheitslücken enthalten, und Datenbank-Migrationen müssen auch in der Produktion zuverlässig funktionieren. Dieser Beitrag beschreibt die konkreten Wartungsaufgaben, die eine Laravel-Anwendung über Jahre hinweg stabil und sicher halten.

Laravel-Releases und Support-Zyklen

Laravel folgt einem vorhersehbaren Release-Rhythmus. Seit Version 6 (September 2019) erscheint jährlich eine neue Major-Version — jeweils im ersten Quartal. Jede Major-Version erhält zwei Jahre lang Bug-Fixes und drei Jahre lang Sicherheitsupdates. Danach endet der offizielle Support vollständig.

Die konkrete Zeitlinie verdeutlicht die Konsequenzen: Laravel 10 (Februar 2023) erhält Bug-Fixes bis August 2024 und Sicherheitspatches bis Februar 2026. Laravel 11 (März 2024) erhält Bug-Fixes bis September 2025 und Sicherheitspatches bis März 2027. Wer im Jahr 2026 noch eine Anwendung auf Laravel 9 betreibt, läuft bereits ohne jeglichen offiziellen Support — keine Bug-Fixes, keine Sicherheitspatches, keine Kompatibilitätsgarantien mit neueren PHP-Versionen.

In regulierten Umgebungen — etwa bei öffentlichen Auftraggebern, im Gesundheitswesen oder bei Anwendungen, die unter die DSGVO fallen — ist der Betrieb auf einer nicht mehr unterstützten Framework-Version ein dokumentierter Risikofaktor. Audits und Zertifizierungen (etwa nach ISO 27001) erfordern, dass eingesetzte Software aktuell gehalten wird. Ein veraltetes Laravel ist ein Befund, der im Audit-Bericht steht.

Ein Major-Upgrade ist kein trivialer Vorgang, aber Laravel macht ihn handhabbar. Jede neue Version liefert einen offiziellen Upgrade Guide, der Breaking Changes dokumentiert — oft auf wenigen Seiten, weil Laravel bewusst die Rückwärtskompatibilität hoch hält. Das Werkzeug Laravel Shift automatisiert einen Großteil der Änderungen: Namespace-Anpassungen, Konfigurationsdateien, veraltete Methoden, geänderte Default-Werte. Shift erzeugt einen Pull Request mit allen notwendigen Modifikationen, der vom Entwicklungsteam reviewed und getestet wird. Die verbleibenden manuellen Anpassungen betreffen typischerweise anwendungsspezifischen Code, der veraltete APIs nutzt, oder Drittanbieter-Pakete, die noch kein Update für die neue Laravel-Version bereitstellen.

Die Upgrade-Strategie sollte Teil der Projektplanung sein, nicht eine Reaktion auf ablaufenden Support. Empfohlen ist, neue Major-Versionen innerhalb von drei bis sechs Monaten nach Release zu übernehmen. Das hält den Abstand klein und den Migrationsaufwand beherrschbar. Wer zwei oder drei Major-Versionen überspringt, steht vor einem erheblich größeren Migrationsaufwand — und vor dem Problem, dass Drittanbieter-Pakete die ältere Version möglicherweise nicht mehr unterstützen.

Neben Laravel selbst muss auch die PHP-Version aktuell gehalten werden. Laravel 11 erfordert mindestens PHP 8.2. PHP 8.1 erreichte im November 2025 das End of Life. Wer die PHP-Version nicht rechtzeitig aktualisiert, kann auch kein Laravel-Upgrade durchführen — die Abhängigkeiten greifen ineinander.

Composer-Dependencies aktuell halten

Eine typische Laravel-Anwendung hat 40 bis 80 direkte Composer-Abhängigkeiten und mehrere Hundert transitive. Jede dieser Abhängigkeiten kann Sicherheitslücken enthalten, die nach ihrer Entdeckung in Datenbanken wie der PHP Security Advisories Database, dem GitHub Advisory Database oder der National Vulnerability Database (NVD) erfasst werden.

Das Werkzeug composer audit prüft die installierte composer.lock gegen bekannte Sicherheitslücken und gibt eine übersichtliche Liste betroffener Pakete mit CVE-Nummern und Schweregrad aus. In der CI/CD-Pipeline lässt sich dieser Check als obligatorischer Schritt einbauen, sodass kein Deployment mit bekannten Schwachstellen möglich ist. Fehlschlägt der Audit, wird der Build rot — und die Entwickler müssen die betroffenen Pakete aktualisieren, bevor neuer Code ausgerollt werden kann.

Regelmäßige Dependency-Updates folgen einem strukturierten Ablauf:

  1. composer outdated zeigt alle verfügbaren Updates mit Angabe der aktuellen, der neuesten Minor- und der neuesten Major-Version. Die Farbcodierung (gelb für Minor, rot für Major) gibt einen schnellen Überblick.
  2. Minor- und Patch-Updates (composer update --with-dependencies) sind in der Regel rückwärtskompatibel und können wöchentlich eingespielt werden. Nach dem Update läuft die vollständige Testsuite. Bestehen alle Tests, kann das Update deployed werden.
  3. Major-Updates erfordern die Prüfung von Changelogs und Breaking Changes. Sie werden einzeln durchgeführt — nicht im Paket mit anderen Major-Updates — und gegen die Testsuite validiert. Jedes Major-Update erhält einen eigenen Branch und Pull Request, um die Änderungen isoliert zu prüfen.
  4. Automatisierte Tools wie Dependabot (GitHub) oder Renovate (plattformunabhängig) erzeugen automatisch Pull Requests für veraltete Abhängigkeiten und lösen die CI-Pipeline aus. Das reduziert den manuellen Aufwand auf die Bewertung und das Mergen der Updates. Renovate lässt sich so konfigurieren, dass Minor- und Patch-Updates automatisch gemergt werden, wenn die Tests bestehen — für Major-Updates bleibt die manuelle Prüfung Pflicht.

Ein häufiger Fehler in der Laravel-Wartung: Updates werden monatelang aufgeschoben, weil “gerade keine Zeit ist” oder “es ja läuft”. Dann haben sich Dutzende veralteter Pakete angesammelt, darunter mehrere mit Breaking Changes, die sich gegenseitig beeinflussen. Das resultierende “große Update” dauert Tage statt Stunden und bringt zwangsläufig unerwartete Probleme. Der bessere Ansatz ist kontinuierliche Pflege — kleine, häufige Updates statt seltener Grossprojekte. Ein wöchentlicher Dependency-Check von 30 Minuten verhindert einen jährlichen Dependency-Albtraum von mehreren Tagen.

Besondere Aufmerksamkeit verdienen Pakete, die tief in die Anwendung integriert sind: das Laravel-Framework selbst, das ORM (Eloquent), Authentifizierungspakete (Sanctum, Passport) und Datenbankabstraktionsschichten. Änderungen an diesen Kernpaketen haben potenziell größere Auswirkungen als Updates von Hilfs-Libraries.

Datenbank-Migrationen und Schema-Änderungen

Laravels Migrationssystem versioniert Datenbankänderungen als PHP-Klassen. Jede Migration hat eine up()- und eine down()-Methode — für die Anwendung und das Zurückrollen der Änderung. In der Entwicklung funktioniert das zuverlässig: php artisan migrate wendet neue Migrationen an, php artisan migrate:rollback nimmt sie zurück. In der Produktion kommen zusätzliche Herausforderungen hinzu.

Locking und Downtime. Schema-Änderungen auf großen Tabellen (ALTER TABLE auf einer Tabelle mit Millionen Zeilen) können bei MySQL/MariaDB Minuten dauern und die Tabelle währenddessen sperren. Für Anwendungen, die Ausfallzeiten nicht tolerieren, gibt es bewährte Strategien: Online-Schema-Change-Tools wie pt-online-schema-change (Percona Toolkit) oder gh-ost (GitHub) führen Änderungen im Hintergrund durch, indem sie eine Kopie der Tabelle erstellen, die Änderungen darauf anwenden und dann die Tabellen atomar tauschen. Alternativ lassen sich Migrationen in mehrere Schritte aufteilen: Zuerst die neue Spalte hinzufügen (schnell, weil keine Datenkonvertierung), dann Daten im Hintergrund migrieren (als Queue-Job), und abschließend die alte Spalte entfernen (schnell). Dieser Ansatz wird als “expand and contract” bezeichnet und ist besonders bei Zero-Downtime-Anforderungen relevant.

Rollback-Strategien. Die down()-Methode in Migrationen ermöglicht ein Zurückrollen. In der Praxis ist ein Rollback jedoch nicht immer verlustfrei. Wenn eine Migration Daten transformiert (etwa eine Spalte von String zu Integer konvertiert) oder Spalten entfernt, gehen diese Informationen beim Rollback verloren. Für kritische Deployments ist deshalb ein vollständiges Datenbank-Backup vor der Migration Pflicht — nicht als Ersatz für die down()-Methode, sondern als zusätzliche Absicherung. Zusätzlich empfiehlt sich ein Blue-Green-Deployment, bei dem die alte Version parallel auf der alten Datenbankversion weiterläuft, bis die neue Version vollständig validiert ist.

Zero-Downtime-Deployments. Laravel Envoyer und ähnliche Deployment-Tools unterstützen atomare Deployments: Der neue Code wird in ein neues Release-Verzeichnis vorbereitet, Abhängigkeiten installiert, Assets kompiliert und Migrationen ausgeführt. Erst wenn alles erfolgreich ist, wird der Symlink auf die neue Version umgeschaltet. Bei fehlgeschlagenen Migrationen bleibt die alte Version aktiv. In Kombination mit Health Checks, die nach dem Symlink-Wechsel automatisch prüfen, ob die Anwendung korrekt antwortet, entsteht ein Deployment-Prozess, der Ausfallzeiten auf wenige Sekunden reduziert.

Schema-Dokumentation. In langlebigen Projekten wachsen Migrationen auf Dutzende oder Hunderte Dateien an. Laravels schema:dump-Befehl (seit Version 8) fasst alle Migrationen in eine einzige SQL-Datei zusammen und schafft damit einen sauberen Startpunkt. Neue Installationen müssen nicht mehr alle historischen Migrationen durchlaufen, sondern starten vom Dump und wenden nur neuere Migrationen an.

Testing als Wartungsinstrument

Tests sind in der Laravel-Wartung noch wichtiger als in der Erstentwicklung. Während der Entwicklung wird neuer Code gegen Tests geschrieben. In der Wartung müssen bestehende Tests sicherstellen, dass Updates und Änderungen nichts kaputt machen. Ohne Testsuite ist jedes Update ein Experiment mit unbekanntem Ausgang — und damit ein Risiko, das verantwortungsvolle IT-Leitung nicht eingehen sollte.

PHPUnit für Unit- und Integrationstests. Laravel integriert PHPUnit nativ und bietet umfangreiche Hilfsklassen: HTTP-Tests (Requests simulieren und Responses prüfen), Datenbank-Tests (mit RefreshDatabase oder DatabaseTransactions für automatisches Rollback nach jedem Test), Queue-Tests (prüfen, ob Jobs dispatched wurden), Event-Tests, Notification-Tests und Mail-Tests. Eine gute Testabdeckung für die Geschäftslogik — mindestens 70 %, idealerweise über 85 % der kritischen Pfade — ist die Voraußetzung dafür, dass Laravel-Updates mit Zuversicht eingespielt werden können. Tests, die bei einem Framework-Update fehlschlagen, zeigen präzise, wo Anpassungen nötig sind.

Laravel Dusk für Browser-Tests. Dusk steuert einen echten Chrome-Browser (über ChromeDriver) und testet die Anwendung aus Nutzerperspektive: Formulare ausfüllen, Buttons klicken, auf AJAX-Responses warten, Seiteninhalte prüfen, Screenshots bei Fehlern erstellen. Browser-Tests fangen Fehler, die Unit-Tests nicht erkennen — etwa JavaScript-Probleme, CSS-Regressions, fehlerhafte Livewire-Interaktionen oder Race Conditions bei asynchronen Requests. Dusk-Tests sind langsamer als PHPUnit-Tests und sollten deshalb auf die kritischsten User Journeys beschränkt werden: Login, Registrierung, Kernworkflows und Checkout-Prozesse.

CI/CD-Pipeline. Tests sind nur dann wertvoll, wenn sie bei jedem Deployment automatisch laufen. Eine CI/CD-Pipeline in Azure DevOps, GitHub Actions oder GitLab CI führt die Testsuite bei jedem Push aus. Die typische Pipeline für ein Laravel-Projekt umfasst: Composer Install, PHPUnit-Tests, Static Analysis (PHPStan oder Psalm), Code Style Check (PHP CS Fixer oder Pint), Composer Audit und optional Dusk-Tests. Fehlgeschlagene Tests blockieren das Deployment. Das ist kein bürokratisches Hindernis, sondern eine Sicherheitsmaßnahme, die verhindert, dass bekannte Fehler in die Produktion gelangen.

Testpflege als laufende Aufgabe. Die Pflege der Testsuite selbst ist eine Wartungsaufgabe, die häufig vernachlässigt wird. Tests müssen an geänderte Anforderungen angepasst werden: Wenn sich ein Formular ändert, müssen die zugehörigen Dusk-Tests aktualisiert werden. Veraltete Tests, die irrelevante Funktionen prüfen, müssen entfernt werden — sie verlangsamen die Pipeline und erzeugen False Positives. Neue Funktionalität braucht neue Tests. Ein Wartungsvertrag sollte diese Aufgabe explizit einschließen, nicht als Nebenprodukt behandeln.

Performance-Monitoring für Laravel-Anwendungen

Performance-Probleme entstehen schleichend. Eine Datenbankabfrage, die mit 10.000 Datensätzen in 50 Millisekunden läuft, braucht mit 500.000 Datensätzen möglicherweise 3 Sekunden. Ein Cache, der einmal richtig konfiguriert wurde, verfehlt seine Wirkung, wenn sich die Zugriffsmuster ändern. Ein Queue-Worker, der anfangs 100 Jobs pro Minute verarbeitet, kommt bei 1.000 Jobs pro Minute nicht mehr hinterher. Kontinuierliches Monitoring macht diese Entwicklungen sichtbar, bevor sie die Nutzererfahrung beeinträchtigen oder zu Ausfällen führen.

Laravel Telescope protokolliert in der Entwicklungsumgebung alle Requests, Datenbankabfragen (mit Ausführungszeit und Binding-Werten), Queue-Jobs, Cache-Operationen, Mail-Versand, Notifications, Events und Log-Einträge. Es zeigt langsame Queries, häufige Cache-Misses, fehlgeschlagene Jobs und unerwartete Exceptions auf einen Blick. Telescope ist ein Analyse- und Debug-Werkzeug, das primär in Entwicklungs- und Staging-Umgebungen eingesetzt wird. Für die Produktion gibt es spezialisierte APM-Lösungen (Application Performance Monitoring) wie New Relic, Datadog oder Sentry, die weniger Overhead verursachen und auf langfristiges Monitoring ausgelegt sind.

Laravel Horizon bietet Echtzeit-Monitoring für Redis-basierte Queues. Dashboard-Metriken zeigen Durchsatz (Jobs pro Minute), Wartezeiten (wie lange ein Job in der Queue wartet, bevor er verarbeitet wird), Fehlschläge (mit Stack Traces) und Worker-Auslastung. Horizon löst Alerts aus, wenn Queues über definierte Schwellwerte hinauswachsen — ein Frühwarnsystem für Lastspitzen, fehlerhafte Jobs oder unzureichende Worker-Kapazität. Die Auto-Balancing-Strategien von Horizon verteilen Worker dynamisch auf Queues mit dem höchsten Bedarf.

Datenbank-Monitoring. Slow Query Logs (in MySQL/MariaDB konfigurierbar ab einer definierten Schwelle, etwa 200 Millisekunden), Index-Analyse (EXPLAIN-Statements) und Query-Profiling sind die Werkzeuge für die Datenbankoptimierung. In Laravel lassen sich Datenbankabfragen über den DB::listen()-Hook protokollieren und analysieren. Fehlende Indizes, N+1-Probleme (erkennbar durch Tools wie Laravel Debugbar oder das preventLazyLoading()-Feature seit Laravel 9) und unnötig komplexe Queries sind die häufigsten Ursachen für Performance-Einbrüche. Regelmäßige Analyse der langsamsten Queries — etwa wöchentlich aus dem Slow Query Log — deckt Optimierungspotenzial auf, bevor es zum Problem wird.

Caching-Strategien. Laravel unterstützt mehrere Cache-Backends: Redis, Memcached, APCu, Datei-basiertes Caching und DynamoDB. Redis ist für die meisten Produktionsumgebungen die beste Wahl: schnell (Sub-Millisekunden-Zugriffe), persistent (optional), vielseitig (Cache, Session-Store, Queue-Backend) und skalierbar (Redis Cluster für horizontale Skalierung). Die Konfiguration von Cache-TTLs, die Auswahl der richtigen Cache-Granularität (ganze Seiten vs. Abfrageergebnisse vs. berechnete Werte) und die regelmäßige Prüfung der Cache-Hit-Rate (sollte über 90 % liegen) gehören zu den laufenden Wartungsaufgaben. Laravels Cache::remember()-Pattern macht das Caching im Code trivial — die Herausforderung liegt in der strategischen Entscheidung, was gecacht wird und wie lange.

Laravel-Wartungsverträge bei TenMedia

TenMedia bietet Wartungsverträge für Laravel-Anwendungen ab 900 EUR monatlich an. Diese Verträge basieren auf monatlichen Stundenkontingenten und umfassen die folgenden Leistungen:

Für Anwendungen mit erhöhten Verfügbarkeitsanforderungen stehen Service Level Agreements zur Verfügung. Die SLA-Stufen definieren garantierte Reaktionszeiten (bis zu 4 Stunden bei kritischen Störungen), Verfügbarkeitsgarantien (bis zu 99,9 %) und priorisierte Bearbeitung.

Die Wartung von PHP-Anwendungen generell — auch außerhalb von Laravel — folgt ähnlichen Prinzipien: Updates, Sicherheitspatches, Monitoring und Testing. Die spezifischen Eigenheiten von Laravel — insbesondere der jährliche Release-Rhythmus, das Ökosystem-Management (Forge, Horizon, Telescope), die Eloquent-spezifische Datenbankpflege und die Integration von Livewire — erfordern jedoch Framework-spezifisches Know-how, das über allgemeine PHP-Wartung hinausgeht.

Weiterführende Informationen