Kai Ole Hartwig
4 Min. Lesezeit
Von

TYPO3 auf FrankenPHP: operative Stolperfallen

FrankenPHPs Worker-Modell ist schnell und angenehm — und ändert leise das mentale Modell für Config-Reloads, Logging und Deploys gegenüber klassischem PHP-FPM. Teil 4 von „The Ops Log“.

TL;DR

TL;DR: Der Worker bedient nur das Frontend, Backend-Requests laufen deshalb als klassisches PHP und übernehmen Config-Edits nach ~2s — aber eine Code-Änderung an einer gepreloadeten Klasse braucht einen Prozess-Neustart. TYPO3-Dateilogging ist über HTTP effektiv tot; Logs nach stderr routen. Und /app ist ein emptyDir — In-Pod-Edits verschwinden bei Neuerzeugung.

Was passiert ist

Stolperfalle 1 — zwei Runtimes in einem Pod. Der FrankenPHP-Worker bedient das Frontend; ein Request-Classifier gibt Backend-/Install-Requests mit 503 aus dem Worker heraus, sodass /typo3, /login und die gesamte Auth-Kette als klassisches PHP mit frischem Bootstrap pro Request laufen. Praktische Konsequenz: Mit opcache.validate_timestamps=On greift eine Änderung an additional.php oder einer nicht gepreloadeten Extension-Klasse innerhalb von ~2s — kein Pod-Neustart nötig. Großartig zum Hotfixen von Config.

Stolperfalle 2 — Preload pinnt Klassen, manche Swaps brauchen trotzdem einen Neustart. Die Kehrseite von Stolperfalle 1: opcache.preload pinnt den TYPO3\CMS\*-Core beim Boot in den Prozess. Tauscht man den Code einer gepreloadeten Klasse unter einem laufenden Worker aus, bekommt man einen duplicate-class-TypeError — die alte Definition ist immer noch gepinnt. Solche Deploys müssen den FrankenPHP-Prozess neu starten, nicht nur neue Dateien ablegen:

was „greift“ hängt davon ab, was sich geändert hat

 

kein Neustart  additional.php, nicht gepreloadete Ext-Klasse   (validate_timestamps=On)
Neustart       alles unter opcache.preload (TYPO3\CMS\*)
Neustart       Klassensignatur-Swaps → duplicate-class TypeError

 

Stolperfalle 3 — Dateilogging ist ein schwarzes Loch über HTTP. Die Log-Writer-Konfiguration zeigt auf einen Pfad, den der CLI-Warmup beschreiben kann, das Arbeitsverzeichnis des HTTP-Workers aber nicht — also liegt typo3_*.log bei null Bytes, und man debuggt blind. Der Ausweg ist, einen Kanal auf PhpErrorLogWriter zu routen, dessen error_log nach /dev/stderr geht — genau das, was kubectl logs liest:

additional.php — Logs sichtbar machen

 

$GLOBALS['TYPO3_CONF_VARS']['LOG'][$vendor][$ext]['writerConfiguration']
  [\Psr\Log\LogLevel::DEBUG]
  [\TYPO3\CMS\Core\Log\Writer\PhpErrorLogWriter::class] = [];

$ kubectl -n kunde-xyz logs <pod> -c app   # ← jetzt taucht der Kanal auf</pod>

 

Stolperfalle 4 — /app ist flüchtig. Das Anwendungsverzeichnis ist ein emptyDir, das Init-Container (ein OCI-Artefakt-Pull plus Setup) bei jedem Pod-Start neu befüllen. Eine Datei im laufenden Pod bearbeiten, um etwas zu testen, und sie ist weg, sobald der Pod neu erzeugt wird. Alles Dauerhafte läuft über das Build-Artefakt und das Deployment — das Pod-Dateisystem ist ein Schmierzettel, keine Quelle der Wahrheit.

Die Lehre

Unter FrankenPHP hat „hat meine Änderung gegriffen?“ drei verschiedene Antworten, je nachdem, ob es Config, eine gepreloadete Klasse oder eine Datei auf der Platte ist. Wissen, welches davon man gerade anfasst, bevor man annimmt, ob ein Neustart nötig ist oder nicht.

Häufige Fragen

Kann ich Hotfixes direkt im laufenden Pod testen?+

Nicht dauerhaft — /app ist ein emptyDir, das bei jedem Pod-Neustart durch Init-Container neu befüllt wird. In-Pod-Edits sind ein Schmierzettel für kurzfristige Tests, kein Ort für dauerhafte Änderungen.

Warum sind TYPO3-Logdateien leer?+

Weil der Log-Writer auf einen Pfad zeigt, den der HTTP-Worker nicht beschreiben kann, obwohl der CLI-Warmup ihn beschreiben könnte. Der Fix ist, einen Kanal auf PhpErrorLogWriter zu routen, der nach stderr schreibt.

Woran erkenne ich, ob ein Deploy einen Neustart braucht?+

Prüfen Sie, ob die geänderte Klasse unter opcache.preload gepinnt ist (typischerweise TYPO3\CMS\*-Core-Klassen) oder ob sich eine Klassensignatur geändert hat — in beiden Fällen ist ein Prozess-Neustart nötig, nicht nur neue Dateien.

Warum greifen Backend-Änderungen schneller als Frontend-Änderungen?+

Weil der FrankenPHP-Worker nur das Frontend bedient — Backend-/Install-Requests laufen als klassisches PHP mit frischem Bootstrap pro Request, wodurch opcache.validate_timestamps normal greift.

Fazit

FrankenPHPs Worker-Modell ist ein echter Betriebsgewinn — schnellere Requests, weniger Overhead — aber es verschiebt, was „ein Neustart ist nötig“ bedeutet, an drei unterschiedliche Stellen: Config, Preload und Dateisystem. Wer diese drei Fälle nicht auseinanderhält, debuggt blind oder startet unnötig neu.

Ich betreibe und härte Ihre TYPO3-Plattform auf FrankenPHP — inklusive der Betriebs-Eigenheiten, die klassisches PHP-FPM-Wissen nicht abdeckt.

Von Worker-Architektur über Preload-Strategie bis zu Logging und Deploy-Pipeline: Ich baue TYPO3-auf-FrankenPHP-Setups, die im Betrieb vorhersehbar bleiben.

Plattform-Betrieb statt Beratung auf Papier: Ich baue und pflege Ihre TYPO3-Plattformen laufend.

Termin buchen →

Über den Autor

Foto von Kai Ole Hartwig.

Kai Ole Hartwig

Freiberuflicher DevSecOps-Berater · OnlyOle Consulting

Programmiert seit 2002 – autodidaktisch gelernt, 2012 mit KO-Web selbständig gemacht. Über 100 Projekte, Fokus auf Security, Performance, Automatisierung und Qualität. Heute freiberuflich: DevSecOps-Beratung, Schulungen und Softwareentwicklung.