4 Punkte von GN⁺ 2024-05-31 | 1 Kommentare | Auf WhatsApp teilen
  • 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
  • Die lokale Ausführung deckt sowohl Webserver als auch CLI ab
    • frankenphp php-server -r public/: stellt das Verzeichnis public/ bereit
    • frankenphp 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/frankenphp stellt das Verzeichnis public/ bereit
    • Im selben Image lassen sich auch CLI-Skripte wie php script.php ausführen
  • Die Konfiguration basiert auf Caddy; in der Beispielkonfiguration wird im Block localhost die Komprimierung aktiviert und mit php_server die 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

 
GN⁺ 2024-05-31
Hacker-News-Kommentare
  • Ich habe seit fast zehn Jahren nicht mehr mit PHP entwickelt, aber diese Landingpage hätte mich beinahe dazu gebracht, wenigstens ein Hello World aufzusetzen.
    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 bin vor etwas mehr als zehn Jahren von PHP zu Golang gewechselt, weil Binary-Deployment so angenehm war.
      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.
    • Eine der besten Landingpages, die ich bisher gesehen habe. Unterhaltsam und sofort verständlich.
  • Ich habe lange C# gemacht und programmiere inzwischen hauptsächlich in PHP 8; es ist eine hervorragende Sprache, um schnell etwas zu bauen.
    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 mache seit 18 Jahren PHP, und mit nginx + php-fpm reichen fünf Minuten für die Konfiguration.
      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.
    • Als weitere Option gibt es auch Nginx Unit: https://unit.nginx.org/
      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
    • Ich konfiguriere PHP kaum, aber nach meiner Erinnerung war es jedes Mal, wenn ich meinen Desktop neu installiert habe, mit apt-get sehr schnell und reibungslos erledigt.
      Außer Apache neu zu starten, fällt mir nichts ein, was ich zusätzlich hätte tun müssen.
    • Ich frage mich, ob die Apache-Konfiguration wirklich so schlimm ist. Mit etwas wie PHP-FPM wirkt sie ziemlich in Ordnung: https://news.ycombinator.com/item?id=40256843
      Es läuft ungefähr auf LoadModule proxy_fcgi_module "/usr/lib/apache2/modules/mod_proxy_fcgi.so" und SetHandler "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=37443911
      Es 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.
    • Zustimmung. Wenn sich eine Kultur etabliert, die statt PostgreSQL/MySQL auf SQLite setzt, kann die gesamte serverseitige Anwendung zu einem einfachen eigenständigen Binary werden.
      Mit einem Binary lässt sie sich auch leichter in eine Electron-App bündeln.
  • In der Entwicklung nutze ich häufig den eingebauten PHP-Webserver: php -S 0.0.0.0:8000 public/index.php
    Er 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
    • Beim eingebauten PHP-Server steht in der Dokumentation ausdrücklich, dass er nicht für den Produktionseinsatz gedacht ist, sondern nur für Entwicklungszwecke.
      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.
    • Wenn man PHP_CLI_SERVER_WORKERS setzt, kann er mit mehreren Threads laufen.
    • Ich frage mich, ob „nicht für die Produktion geeignet“ nur eine Frage der Performance ist.
      Bei einer kleinen Website mit wenigen Nutzern würde ich gern wissen, was einem im Vergleich zu anderen „produktionsreifen“ Umgebungen fehlt.
    • Soweit ich weiß, löst es genau die genannten Probleme, wegen denen er nicht produktionsgeeignet ist: Single-Threaded und langsam. Vermutlich löst es auch noch weitere Probleme.
  • Ich habe es selbst ausprobiert, und es war wirklich langsam; außerdem schien es die Cores nicht richtig zu nutzen. Ich habe lange in die lückenhafte Dokumentation geschaut, konnte es aber nicht lösen.
    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.
    • Ich bin der Entwickler von FrankenPHP. Ich hätte wirklich gern ein reproduzierbares Beispiel.

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

  • Wenn ihr eure Erfahrungen teilt, hilft das bei der Lösung: https://github.com/dunglas/frankenphp/discussions/294
    Das ist eine ziemlich seltsame Situation, da Caddy selbst auch zusammen mit PHP eine sehr gute Performance liefert
  • Bin gespannt, wie es in den TechEmpower-Benchmarks abschneiden wird: https://www.techempower.com/benchmarks/#hw=ph&test=fortune&s...
    Aktuell steht es ganz unten mit did not complete
  • Verwandter Beitrag: Show HN: FrankenPHP, ein in Go geschriebener App-Server für PHP - https://news.ycombinator.com/item?id=33205282 - Oktober 2022, 83 Kommentare
  • https://github.com/dunglas/frankenphp/discussions/294
    Es gibt ein Performance-Problem. Abgesehen davon ist es ein wirklich vielversprechendes Projekt
    • Wenn ich es nur reproduzieren könnte, würde ich mir gern 2 Wochen Urlaub von der Arbeit nehmen und es beheben. Niemand hat erklärt, wie man es reproduziert
  • Ich habe WordPress mit FrankenPHP und Apache Mod-PHP benchmarked, aber keinen Beleg gesehen, dass FPHP gewinnt
    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
    • Anders als Laravel und Symfony unterstützt WordPress den Worker-Modus von FrankenPHP noch nicht, daher gibt es nicht viele Performance-Vorteile
      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
    • Vielleicht wird der Name nur verwendet, weil er vertraut ist, aber standardmäßig sollte man bei Apache proxy_fcgi nutzen
      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/frankenphp
    Wenn 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-php sowie die Konfiguration von /etc/apache2/sites-enabled/000-default.conf
    Zusammen 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
    • Ich habe vor einem Monat bei einer Firma angefangen, die mod_php verwendet, und es ist schmerzhaft
      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
    • Wenn ich mich nicht irre, wird das wohl nicht funktionieren. Leitet der standardmäßige virtuelle Host 000-default.conf von Apache 443 auf 80 um?
  • Schön, das auf der HN-Startseite zu sehen
    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