Kurz gesagt: Um PHP in Containern zu betreiben, wählen Sie die passende Variante des offiziellen Images (fpm, apache oder cli), aktivieren die Produktions-php.ini, installieren nur benötigte Erweiterungen und setzen Speicher- und Prozessgrenzen, die zueinander passen. Container sind unveränderlich: Ein PHP-Sicherheitsupdate wie zu PHP2Shell wirkt erst, wenn das Image neu gebaut und jeder Container neu gestartet ist. Dieser Neubau gehört deshalb als fester Prozess in jeden Container-Betrieb.
Warum PHP in Containern?
Container verpacken PHP, Erweiterungen und Konfiguration in ein Image, das auf jedem Server gleich läuft. Für Unternehmen bedeutet das: weniger Überraschungen zwischen Test und Produktion, schnellere Wiederherstellung und klare Versionsstände. Für die Sicherheit bedeutet es aber auch eine neue Pflicht: Niemand spielt in einem Container automatisch Updates ein.
Diese Seite behandelt den laufenden Betrieb. Wie Sie bestehende Container konkret gegen PHP2Shell patchen, steht unter PHP in Docker-Containern patchen.
Die richtige Image-Variante wählen
| Variante | Inhalt | Typischer Einsatz |
|---|---|---|
php:<version>-fpm |
PHP-FPM, braucht einen vorgeschalteten Webserver | Produktion mit Nginx, Caddy oder einem Ingress |
php:<version>-apache |
Apache mit mod_php, standardmäßig mpm_prefork | einfache Aufbauten, ältere Anwendungen |
php:<version>-cli |
Kommandozeile, enthält als einzige Variante auch php-cgi | Cronjobs, Queue-Worker, Build-Schritte |
…-alpine |
auf Alpine Linux mit musl | kleine Images, bei manchen Erweiterungen Anpassungen nötig |
…-bookworm, …-trixie |
auf der genannten Debian-Version | feste Basis für reproduzierbare Builds |
Für neue Projekte empfiehlt sich in der Regel die fpm-Variante mit getrenntem Webserver-Container. Bei mod_php sieht das PHP-Team im Zusammenhang mit PHP2Shell das höchste Risiko; wer das apache-Image nutzt, betreibt genau diese Betriebsart.
Ein Produktions-Image bauen
Ein schlankes Beispiel für eine Anwendung mit MySQL-Zugriff:
FROM php:8.4-fpm-alpine
# Produktionskonfiguration aktivieren (laut Image-Doku dringend empfohlen)
RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini"
# Nur benötigte Erweiterungen
RUN docker-php-ext-install -j"$(nproc)" pdo_mysql
# Eigene Einstellungen
COPY zz-sicherheit.ini "$PHP_INI_DIR/conf.d/"
# Code gehört root; die FPM-Worker laufen als www-data und können ihn nur lesen
COPY . /var/www/html
Die Hilfsskripte des Images übernehmen das Bauen von Erweiterungen: docker-php-ext-configure für Optionen, docker-php-ext-install zum Bauen, docker-php-ext-enable zum Aktivieren, etwa nach pecl install. Wird mit docker-php-source der Quellcode entpackt, sollte er laut Doku in derselben Schicht wieder gelöscht werden. Die Datei zz-sicherheit.ini könnte so aussehen:
expose_php = Off
display_errors = Off
log_errors = On
session.use_strict_mode = 1
session.cookie_httponly = 1
Zwei weitere Grundsätze machen Images robuster. Erstens enthält das ausgelieferte Image nur, was zur Laufzeit gebraucht wird; Compiler, Paket-Caches und Testdateien gehören in eine eigene Build-Stufe. Zweitens darf der Benutzer, unter dem PHP läuft, nur dort schreiben, wo es nötig ist, etwa in Upload- oder Cache-Verzeichnissen auf eingebundenen Volumes. Viele Teams betreiben den Container zusätzlich mit schreibgeschütztem Dateisystem. Eine eingeschleuste PHP-Datei hat es dann deutlich schwerer, dauerhaft zu bleiben, und jeder Neustart stellt den sauberen Stand des Images wieder her. Das ersetzt keine Untersuchung nach einem Vorfall, verkleinert aber die Angriffsfläche spürbar.
Prozesse, Speicher und Logs im Container
Drei Stellschrauben bestimmen, ob ein PHP-Container stabil läuft.
- Zahl der Worker:
pm.max_childrenim FPM-Pool legt fest, wie viele Anfragen gleichzeitig bearbeitet werden. Jeder Worker kann bis zumemory_limitbelegen. - Speichergrenze des Containers: Sie begrenzt alle Prozesse zusammen. Als grobe Regel gilt: Worker-Zahl mal Speicher je Worker plus Reserve muss unter das Limit passen, sonst beendet das System Prozesse.
- Logs: Container schreiben Logs auf die Standardausgabe. In PHP-FPM leitet
catch_workers_output = yesAusgaben der Worker ins Hauptlog; ohne die Einstellung landen sie laut Handbuch im Nichts.
Hilfreich ist außerdem request_terminate_timeout, das einzelne Anfragen nach einer Zeitspanne beendet, wenn max_execution_time nicht greift. Wie Sie Container im Cluster betreiben, beschreibt PHP in Kubernetes patchen.
Container und Sicherheit: was PHP2Shell gezeigt hat
Bei PHP2Shell spielen Container eine doppelte Rolle. Zum einen sind sie eine Hilfe: php.net empfiehlt als Übergangsmaßnahme zu CVE-2026-109618, memory_limit=-1 mit einer Speichergrenze über Container oder cgroup zu kombinieren, idealerweise so, dass nur der betroffene Worker beendet wird. RLIMIT_AS und RLIMIT_DATA sind dafür laut php.net ungeeignet. Diese Maßnahme ist kein vollständiger Schutz und ersetzt das Update nicht.
Zum anderen sind Container eine Falle, wenn Images nicht neu gebaut werden. Ein Image mit PHP 8.4.26 bleibt verwundbar, egal wie oft der Container neu startet. Erst ein Neubau auf 8.4.27 oder neuer und der Austausch aller laufenden Container schließen die Lücke. Kontrollieren lässt sich der Stand direkt im laufenden Container:
docker exec <container> php -v
docker exec <container> php-fpm -v
docker exec <container> php -r 'var_dump(ini_get("memory_hard_limit_percent"));'
Liefert der letzte Befehl bool(false), kennt PHP die mit den Fix-Versionen eingeführte Direktive nicht; laut Handbuch ist die Version dann betroffen. Dauerhaft hilft nur ein automatischer Neubau, wie unter CI/CD: PHP-Images automatisch neu bauen beschrieben.
Legen Sie im Dockerfile die genaue PHP-Version im Tag fest und erhöhen Sie sie bewusst. So ist im Code nachvollziehbar, wann welche Version ausgerollt wurde.
Wie hilft PHP SOS konkret?
Bei der Server-Härtung für PHP-Webserver kümmern wir uns auch um Container:
- Images prüfen: Basis-Image, PHP-Version, Erweiterungen und Konfiguration jedes Images.
- Konfiguration härten: Produktions-ini, schlanke Erweiterungsliste, passende Worker- und Speichergrenzen.
- Neubau einrichten: Ein Ablauf, der Images bei neuen PHP-Releases neu baut und ausrollt.
- Laufzeit kontrollieren: Wir belegen, dass in jedem laufenden Container die korrigierte Version läuft.
Häufige Fragen
Welche Variante des PHP-Images ist die richtige?
Für Nginx oder einen anderen Proxy die fpm-Variante, für einen einfachen Aufbau mit Apache die apache-Variante, für Skripte und Cronjobs die cli-Variante. Alpine-Varianten sind kleiner, basieren aber auf musl statt glibc, was bei manchen Erweiterungen auffällt.
Wird PHP im Container automatisch aktualisiert?
Nein. Ein laufender Container ändert sich nicht. Sie müssen das Image mit der neuen PHP-Version neu bauen und die Container neu starten. Erst dann läuft die korrigierte Version.
Wie verhalten sich memory_limit und das Container-Limit?
memory_limit begrenzt jede einzelne PHP-Anfrage, das Container-Limit den ganzen Container. Beide müssen zusammenpassen: Die Zahl der Worker mal Speicher je Worker sollte unter dem Container-Limit liegen.
Brauche ich in Containern eine php.ini?
Ja. Die offiziellen Images liefern php.ini-development und php.ini-production als Vorlagen mit. Für Produktion empfiehlt die Image-Dokumentation ausdrücklich die Produktionsvorlage; eigene Einstellungen kommen nach conf.d.