FrankenPHP: Moderner PHP-App-Server
(frankenphp.dev)- Für Deployment-Workflows, die PHP-Apps ohne separates PHP-FPM betreiben wollen, ist FrankenPHP ein Go-basierter App-Server mit einem offiziellen PHP-Laufzeitmodul direkt in Caddy, der PHP-Web-Apps und CLI-Skripte mit einem einzigen Befehl ausführt
- HTTP/1.1, HTTP/2, HTTP/3, automatische HTTPS-Zertifikate, Brotli-/Zstandard-/Gzip-Komprimierung, strukturiertes Logging und Prometheus-Metriken sind als Standardfunktionen gebündelt und reduzieren den Konfigurationsaufwand des Servers
- Der Worker mode bootet die App einmal und hält sie im Speicher; laut dem app-eigenen Benchmark von API Platform erzielte er ein 3,5-fach schnelleres Ergebnis als FPM
- Kompatibel mit PHP 8.2+, den meisten PHP-Erweiterungen und Caddy-Modulen; beliebte Erweiterungen wie OPcache und XDebug werden nativ unterstützt
- Unterstützt Docker-Images, Kubernetes, Cloud-Plattformen und die Verteilung als eigenständige statische Binärdatei, wodurch sich die Deployment-Einheit für PHP-Apps vereinfachen lässt
Ausführungsmodell und grundlegender Nutzungsablauf
- FrankenPHP versteht sich als moderner, in Go geschriebener PHP-App-Server und richtet Installation und Ausführung eines PHP-App-Servers rund um ein Ein-Befehl-Modell aus
- Die Installationsbeispiele sind nach Betriebssystem getrennt
- Linux/macOS:
curl https://frankenphp.dev/install.sh | sh - Windows PowerShell:
irm https://frankenphp.dev/install.ps1 | iex
- Linux/macOS:
- Die lokale Ausführung deckt sowohl Webserver als auch CLI ab
frankenphp php-server -r public/: stellt das Verzeichnispublic/bereitfrankenphp php-cli script.php: führt ein PHP-Skript auf der Kommandozeile aus
- Auch die Docker-Ausführung erfolgt mit demselben Image
- Das Image
dunglas/frankenphpstellt das Verzeichnispublic/bereit - Im selben Image lassen sich auch CLI-Skripte wie
php script.phpausführen
- Das Image
- Die Konfiguration basiert auf Caddy; in der Beispielkonfiguration wird im Block
localhostdie Komprimierung aktiviert und mitphp_serverdie PHP-Dateien und statischen Assets des aktuellen Verzeichnisses verarbeitet
Serverfunktionen und PHP-Kompatibilität
-
Webserver-Funktionen
- Das offizielle PHP-Laufzeitmodul ist direkt in Caddy integriert
- Native Unterstützung für HTTP/1.1, HTTP/2 und HTTP/3
- Erstellung, Erneuerung und Widerruf von HTTPS-Zertifikaten über Let’s Encrypt oder ZeroSSL werden automatisiert
- Brotli-, Zstandard- und Gzip-Komprimierung werden standardmäßig unterstützt
- Enthält strukturiertes Logging und Prometheus-Unterstützung
-
PHP-Laufzeitumgebung
- Kompatibel mit PHP 8.2+, den meisten PHP-Erweiterungen und allen Caddy-Modulen
- Beliebte PHP-Erweiterungen einschließlich OPcache und XDebug werden nativ unterstützt
- PHP-FPM ist nicht erforderlich; verwendet wird ein eigenes SAPI für Go-Webserver
Worker mode und leistungsorientierte Funktionen
- Der Worker mode bootet die Anwendung einmal und hält sie anschließend im Speicher, sodass sie Anfragen innerhalb weniger Millisekunden bearbeiten kann
- Wird nativ von Symfony, API Platform und Laravel unterstützt
- Verwendet bestehende PHP-Superglobals ohne PSR-7
- Auch wenn eine App nicht mit dem Worker mode kompatibel ist, kann sie weiterhin normal ausgeliefert werden
- Ein Watcher zum automatischen Neustart von Workern bei Codeänderungen ist vorhanden
- Laut eigener Vorstellung erreicht der Modus in internen Benchmarks mit einer API-Platform-App eine 3,5-fach höhere Leistung als FPM
Deployment und Packaging
- Mit dem Docker-Image lassen sich Cloud-native Apps deployen
- Kompatibel mit Kubernetes und modernen Cloud-Plattformen
- PHP-Webanwendungen und Kommandozeilen-Tools lassen sich als eigenständige statische Binärdatei paketieren
- Beschrieben wird der Betrieb als ein Service und eine Binärdatei, ohne dass externe Dienste nötig sind
Zusätzliche Webplattform-Funktionen
- Unterstützt 103 Early Hints, vorgestellt mit Verweis auf einen Cloudflare-Beitrag als Funktion zur Verbesserung der Ladezeit von Websites um 30 %
- Über den integrierten Mercure-Hub können Ereignisse aus einer PHP-App an verbundene Browser gesendet werden, die die Payload sofort als JavaScript-Event empfangen können
- Graceful reload unterstützt Deployments ohne Downtime
1 Kommentare
Hacker-News-Kommentare
Die Elefanten-Frankenstein-Figur ist absonderlich, hässlich und niedlich zugleich. Design, Farben, Texte und Animationen sind ebenfalls sauber umgesetzt. Aus Sicht von jemandem, der eine Weile weg von der PHP-Entwicklung war, kommt das Wertversprechen gut rüber, und es wirkt gut geeignet, um schnell mit etwas Kleinem loszulegen.
Ich will nicht acht Container starten, nur um schlechte Software oder verhedderte Abhängigkeiten zu isolieren. Ich mag es nicht, statt installierbarer Software ein „Auf meinem Rechner läuft es“ zu verpacken und in die Welt zu werfen. Aus Nostalgie könnte ich es mir einmal ansehen, aber ich bin mir nicht sicher, ob ich so etwas noch in eine Produktionsumgebung stellen möchte.
Statt in eine Richtung wie früher bei LAMP zu gehen, wo eine eher komplexe Apache-Konfiguration nötig war, sollte sich die Sprache in diese Richtung bewegen.
Ich werde mir das hier auch einmal ansehen, aber weder bei nginx noch bei Apache hatte ich je einen Flaschenhals. Beides lässt sich in höchstens ein paar Minuten starten.
Es läuft wie Apache + mod_php als einzelner Service, kümmert sich um Multiprocessing für PHP und andere Sprachen, statische Dateien und Reverse Proxy und kann sich selbst und PHP zur Laufzeit über Dateien oder Sockets in einer einzigen Konfiguration verwalten: https://unit.nginx.org/configuration/#php
Ein reales Konfigurationsbeispiel ist https://github.com/PrivateBin/docker-unit-alpine/blob/master..., und auch das resultierende Container-Image lässt sich ziemlich klein halten: https://hub.docker.com/r/privatebin/unit-alpine
Außer Apache neu zu starten, fällt mir nichts ein, was ich zusätzlich hätte tun müssen.
Es läuft ungefähr auf
LoadModule proxy_fcgi_module "/usr/lib/apache2/modules/mod_proxy_fcgi.so"undSetHandler "proxy:fcgi://127.0.0.1:9000"hinaus. Es gibt auch ein Nginx-Beispiel, das konzeptionell ähnlich zur Apache-Konfiguration ist, inklusive Installation der nötigen Pakete: https://news.ycombinator.com/item?id=37443911Es gibt auch vorgebaute Container-Images, mit denen man ein ähnliches Ergebnis bekommt, aber wenn man sehen will, wie es intern läuft, kann man es selbst machen. Es ist definitiv einfacher, als früher Java-Application-Server wie Tomcat oder GlassFish manuell zu konfigurieren, und auch wenn ein einzelner Ausführungsbefehl in jeder Umgebung besser ist, ist LAMP im Vergleich zu anderen Stacks nicht so schlecht.
Mit einem Binary lässt sie sich auch leichter in eine Electron-App bündeln.
php -S 0.0.0.0:8000 public/index.phpEr ist aber Single-Threaded und langsam, also nichts für die Produktion. FrankenPHP sieht vielversprechend aus, aber auch das Problem mit Core-/Thread-Limits[2] könnte in der Produktion relevant werden. Trotzdem könnte ich es einmal im Projekt pure-todo[1] einsetzen und schauen, ob dasselbe Problem auftritt. Das Standard-Docker-Image sieht ziemlich gut aus.
1: https://github.com/sandreas/pure-todo
2: https://github.com/dunglas/frankenphp/discussions/294
Siehe Warnhinweis oben auf der Seite: https://www.php.net/manual/en/features.commandline.webserver...
Ich bin mir auch nicht sicher, ob es in diesem Kontext fair ist, ihn als Vergleich heranzuziehen.
PHP_CLI_SERVER_WORKERSsetzt, kann er mit mehreren Threads laufen.Bei einer kleinen Website mit wenigen Nutzern würde ich gern wissen, was einem im Vergleich zu anderen „produktionsreifen“ Umgebungen fehlt.
Es heißt, mit ein paar Befehlen sei es produktionsbereit und 3,5-mal schneller als FPM, aber in meiner Umgebung lief es ungefähr bei 1 % der FPM-Performance. Ich habe auch die ausführbare Datei ausprobiert, aber es war dasselbe Problem; bei Hello World hätte ich mindestens 200K rps erwartet.
In den meisten Benchmarks ist FrankenPHP bei aktiviertem Worker-Modus in der Regel deutlich schneller als FPM, ungefähr um den Faktor 3. Es gibt aber dennoch einige Ausnahmefälle, die gemeinsam mit den PHP-Maintainern behoben werden
Das ist eine ziemlich seltsame Situation, da Caddy selbst auch zusammen mit PHP eine sehr gute Performance liefert
Aktuell steht es ganz unten mit did not complete
Es gibt ein Performance-Problem. Abgesehen davon ist es ein wirklich vielversprechendes Projekt
Allerdings bin ich nicht tief eingestiegen, und die Tests liefen nicht in einer typischen Konfiguration, sondern in Docker. Auch WordPress war fast in der Standardeinstellung, ohne schwergewichtiges Theme o. Ä., also keine realistischen Bedingungen. Trotzdem möchte ich den Test noch einmal durchführen und besser verstehen
Mit 103 Early Hints lassen sich allerdings Assets vorab laden und die Seitenlade-Latenz um 30 % reduzieren. Außerdem macht FrankenPHP es einfacher, HTTP-Cache für WordPress zu aktivieren, und vereinfacht das Deployment. Es gibt auch ein dediziertes Projekt für WordPress und FrankenPHP, mit einem eingebauten, auf WordPress zugeschnittenen HTTP-Cache auf Basis der Go-Bibliothek Souin: https://github.com/StephenMiracle/frankenwp
So lässt sich etwas Apache-Speicher sparen und es bleibt mehr Spielraum, um weitere PHP-Requests zu verarbeiten
docker run -v $PWD:/app/public -p 443:443 \ dunglas/frankenphpWenn man selbst einen Docker-Container bauen möchte, der eine App bereitstellt, dürften die folgenden Befehle ausreichen, um ein frisches Debian in den benötigten Container zu verwandeln:
apt install -y apache2 libapache2-mod-phpsowie die Konfiguration von/etc/apache2/sites-enabled/000-default.confZusammen mit Freunden pflege ich ein Repository, das zeigt, wie man in mehreren beliebten Sprachen und Frameworks von null zu einer laufenden Webanwendung kommt: https://github.com/no-gravity/web_app_from_scratch
Jedes Mal, wenn ich xdebug aktiviere, muss ich nach der Debugging-Session Apache neu starten. Seit gestern habe ich begonnen, apache2 so zu konfigurieren, dass es php-fpm nutzt; zumindest für die Entwicklungsumgebung frage ich mich, ob dieses FrankenPHP für uns passen würde. Allerdings finde ich in der Dokumentation nicht, wie man PHP-Erweiterungen installiert
000-default.confvon Apache 443 auf 80 um?FPM und seine Shared-Nothing-Architektur waren zwar vor langer Zeit ein Kern des Erfolgs von PHP, aber zugleich habe ich das Gefühl, dass sie PHP auch gefesselt haben