FrankenPHP: un servidor moderno para apps PHP
(frankenphp.dev)- En flujos de despliegue que buscan levantar apps PHP sin PHP-FPM por separado, FrankenPHP es un servidor de apps basado en Go que incorpora el ejecutor oficial de PHP en Caddy, permitiendo ejecutar apps web PHP y scripts CLI con un solo comando
- Agrupa funciones básicas como HTTP/1.1, HTTP/2, HTTP/3, certificados HTTPS automáticos, compresión Brotli/Zstandard/Gzip, logging estructurado y métricas de Prometheus para reducir la configuración del servidor
- Explica que Worker mode arranca la app una sola vez y la mantiene en memoria, y que en un benchmark propio de una app de API Platform obtuvo un resultado 3.5 veces más rápido que FPM
- Es compatible con PHP 8.2+, la mayoría de las extensiones de PHP y módulos de Caddy, y también ofrece soporte nativo para extensiones populares como OPcache y XDebug
- Soporta imágenes Docker, Kubernetes, plataformas cloud y despliegue como binario estático independiente, lo que puede simplificar la unidad de despliegue de las apps PHP
Forma de ejecución y flujo básico de uso
- FrankenPHP apunta a ser un servidor moderno para apps PHP escrito en Go, con instalación y ejecución de servidores de apps PHP centradas en un solo comando
- Los ejemplos de instalación se dividen por sistema operativo
- Linux/macOS:
curl https://frankenphp.dev/install.sh | sh - Windows PowerShell:
irm https://frankenphp.dev/install.ps1 | iex
- Linux/macOS:
- La ejecución local cubre tanto el servidor web como CLI
frankenphp php-server -r public/: sirve el directoriopublic/frankenphp php-cli script.php: ejecuta un script PHP de línea de comandos
- La ejecución con Docker también se maneja con la misma imagen
- Sirve el directorio
public/con la imagendunglas/frankenphp - En la misma imagen se pueden ejecutar scripts CLI como
php script.php
- Sirve el directorio
- La configuración está basada en Caddy, y la configuración de ejemplo activa la compresión dentro de un bloque
localhosty procesa los archivos PHP y assets estáticos del directorio actual conphp_server
Funciones del servidor y compatibilidad con PHP
-
Funciones de servidor web
- Incorpora el ejecutor oficial de PHP en Caddy
- Ofrece soporte nativo para HTTP/1.1, HTTP/2 y HTTP/3
- Automatiza la creación, renovación y revocación de certificados HTTPS mediante Let’s Encrypt o ZeroSSL
- Incluye soporte básico para compresión Brotli, Zstandard y Gzip
- Incluye logging estructurado y soporte para Prometheus
-
Entorno de ejecución PHP
- Es compatible con PHP 8.2+, la mayoría de las extensiones de PHP y todos los módulos de Caddy
- Soporta de forma nativa extensiones PHP populares, incluidas OPcache y XDebug
- No necesita PHP-FPM y usa su propia SAPI creada para un servidor web en Go
Worker mode y funciones orientadas al rendimiento
- Worker mode arranca la aplicación una sola vez y luego la mantiene en memoria, dejándola lista para procesar solicitudes en unos pocos milisegundos
- Tiene soporte nativo en Symfony, API Platform y Laravel
- Usa los superglobales PHP existentes, sin PSR-7
- Aunque la app no sea compatible con Worker mode, se puede servir tal cual
- Ofrece un watcher que reinicia automáticamente los workers cuando cambia el código
- Presenta que, en un benchmark propio basado en una app de API Platform, mostró un rendimiento 3.5 veces más rápido que FPM
Despliegue y empaquetado
- Permite desplegar apps cloud native con imágenes Docker
- Es compatible con Kubernetes y plataformas cloud modernas
- Permite empaquetar aplicaciones web PHP y herramientas de línea de comandos como binarios estáticos independientes
- Explica que se ejecuta como un solo servicio y un solo binario, sin necesidad de servicios externos
Funciones adicionales de plataforma web
- Soporta 103 Early Hints y lo presenta, con base en un artículo de Cloudflare, como una función que puede mejorar el tiempo de carga de los sitios web en un 30%
- A través del hub Mercure integrado, las apps PHP pueden enviar eventos a navegadores conectados, y el navegador puede recibir el payload de inmediato como eventos JavaScript
- Soporta despliegues sin interrupción mediante Graceful reload
1 comentarios
Comentarios de Hacker News
El personaje del elefante Frankenstein es raro, feo y tierno a la vez. El diseño, los colores, los textos y las animaciones están muy bien logrados. Desde la perspectiva de alguien que ha estado alejado del desarrollo en PHP por un tiempo, la propuesta de valor se entiende muy bien y parece ideal para empezar rápido con algo pequeño
No quiero levantar 8 contenedores para aislar software mediocre o dependencias enredadas. No me gusta eso de no entregar software instalable y en su lugar envolver un “en mi máquina funciona” para lanzarlo al mundo. Tal vez lo pruebe por nostalgia, pero no sé si querría volver a meter algo así en producción
En vez de ir por la ruta de configuraciones de Apache algo complejas como en los viejos tiempos de LAMP, el lenguaje debería ir más en esta dirección
También pienso probar esto, pero nunca me he topado con cuellos de botella ni en nginx ni en Apache. Levantar cualquiera de los dos me toma solo unos minutos, como mucho
Corre como un solo servicio, como Apache + mod_php, y maneja multiprocesamiento de PHP y otros lenguajes, archivos estáticos y reverse proxy, además de poder gestionar tanto a sí mismo como a PHP en una sola configuración usando archivos o sockets en tiempo de ejecución: https://unit.nginx.org/configuration/#php
Un ejemplo de configuración real está en https://github.com/PrivateBin/docker-unit-alpine/blob/master..., y la imagen de contenedor resultante también puede quedar bastante pequeña: https://hub.docker.com/r/privatebin/unit-alpine
No recuerdo haber hecho nada más aparte de reiniciar Apache
Es básicamente
LoadModule proxy_fcgi_module "/usr/lib/apache2/modules/mod_proxy_fcgi.so"ySetHandler "proxy:fcgi://127.0.0.1:9000". También hay ejemplos en Nginx, configurado de una forma conceptualmente parecida a Apache, e incluyendo la instalación de los paquetes necesarios: https://news.ycombinator.com/item?id=37443911También hay imágenes de contenedor precompiladas con resultados parecidos, pero si quieres ver cómo funciona por dentro, puedes hacerlo tú mismo. Sin duda es más fácil que configurar manualmente Tomcat o GlassFish en los viejos servidores de aplicaciones Java, y aunque un solo comando para ejecutar siempre es mejor en cualquier entorno, LAMP no está tan mal frente a otros stacks
Y si tienes un binario, también es fácil empaquetarlo dentro de una app de Electron
php -S 0.0.0.0:8000 public/index.phpPero es de un solo hilo y lento, así que no es para producción. FrankenPHP se ve prometedor, pero el problema de límites de núcleos/hilos[2] también parece que podría ser un problema en producción. Aun así, podría probarlo en el proyecto pure-todo[1] para ver si aparece el mismo problema. La imagen base de Docker se ve bastante bien
1: https://github.com/sandreas/pure-todo
2: https://github.com/dunglas/frankenphp/discussions/294
Mira la advertencia al inicio de la página: https://www.php.net/manual/en/features.commandline.webserver...
En ese contexto, ni siquiera estoy seguro de que sea justo usarlo como punto de comparación
PHP_CLI_SERVER_WORKERS, puede ejecutarse con múltiples hilosSi se trata de un sitio pequeño con pocos usuarios, me gustaría saber qué estaría faltando frente a otros entornos “listos para producción”
Dicen que queda listo para producción con unos cuantos comandos y que es 3.5 veces más rápido que FPM, pero en mi entorno funcionó como al 1% del rendimiento de FPM. También probé el ejecutable y pasó lo mismo; para un hello world esperaría al menos 200K rps
En la mayoría de los benchmarks, cuando el modo worker está activado, FrankenPHP suele ser mucho más rápido que FPM, aproximadamente 3 veces. Aun así, hay algunos casos excepcionales y lo están corrigiendo junto con los mantenedores de PHP
Caddy en sí, incluso usándolo con PHP, da un rendimiento muy bueno, así que es una situación bastante extraña
Por ahora aparece hasta abajo como did not complete
Tiene problemas de rendimiento. Fuera de eso, es un proyecto realmente prometedor
Eso sí, no investigué a fondo y la prueba tampoco fue en una configuración normal, sino dentro de Docker. WordPress también estaba casi en configuración por defecto, sin temas pesados ni nada así, así que no eran condiciones realistas. Aun así, quiero volver a hacer la prueba y entenderlo mejor
Aun así, con 103 Early Hints se pueden precargar recursos y reducir en 30% la latencia de carga de la página. Además, FrankenPHP facilita activar caché HTTP en WordPress y simplifica el despliegue. Incluso existe un proyecto dedicado a WordPress y FrankenPHP, que incluye una caché HTTP integrada adaptada para WordPress usando la librería Souin para Go: https://github.com/StephenMiracle/frankenwp
Eso puede ahorrar un poco más de memoria en Apache y dejar margen para manejar más solicitudes PHP
docker run -v $PWD:/app/public -p 443:443 \ dunglas/frankenphpSi quieres construir directamente un contenedor Docker para servir la app, parecería que bastan estos comandos para convertir un Debian nuevo en el contenedor necesario:
apt install -y apache2 libapache2-mod-phpy la configuración de/etc/apache2/sites-enabled/000-default.confMantengo con amigos un repositorio que muestra el proceso, desde cero hasta una aplicación web funcionando, con varios lenguajes y frameworks populares: https://github.com/no-gravity/web_app_from_scratch
Cada vez que activo xdebug, después de la sesión de depuración tengo que reiniciar Apache. Desde ayer empecé a configurar apache2 para usar php-fpm, y me pregunto si al menos en el entorno de desarrollo este FrankenPHP nos quedaría bien. Eso sí, no encuentro en la documentación cómo instalar extensiones de PHP
000-default.confde Apache por defecto redirige de 443 a 80?FPM y su arquitectura sin memoria compartida fueron clave en el éxito de PHP hace mucho tiempo, pero al mismo tiempo siento que también han sido una limitación para PHP