Durante mucho tiempo, el ecosistema de PHP ha estado prácticamente limitado a la ejecución de las aplicaciones mediante CLI o a través de Apache o Nginx combinados con FCGI o PHP-FPM. Este enfoque responde perfectamente al modelo de PHP en el que entre distintas peticiones o ejecuciones no se comparte ningún recurso, básicamente la aplicación se ejecuta desde 0 en cada invocación. Esto cambió hace no mucho tiempo con la introducción de servidores de aplicaciones y librerías que introducen nuevas formas de ejecutar nuestras aplicaciones como Sswoole, RoadRunner o bref.
Con estos cambios, junto con la adopción del cloud por parte de la industria y en concreto del ecosistema de PHP, Symfony decidió lanzar su componente symfony/runtime que permite abstraer la aplicación del entorno en el que se ejecuta de modo que facilita el uso de entornos o arquitecturas distintas a las propuestas inicialmente. Es precisamente gracias a esto que hoy podemos hablar de cómo hacer que nuestra aplicación Symfony funcione sobre un servidor de reciente creación llamado FrankenPHP, de una forma tan sencilla como la que veremos en este artículo.
¿Qué es FrankenPHP?
Tabla de contenidos
ToggleSe define como un servidor de aplicaciones moderno para PHP construido sobre el servidor web Caddy, y es precisamente el hecho de estar construido utilizando Caddy que le proporciona soporte para funcionalidades muy recientes que todavía no están extendidas en otros entornos.
Algunos de los puntos fuertes de FrankenPHP son los siguientes:
- Está desarrollado con el foco puesto en su uso dentro de contenedores.
- Permite ejecutar la aplicación en worker mode mejorando de manera sustancial los tiempos de carga.
- Añade soporte para flujos en tiempo real mediante Mercure, que está integrado directamente.
Además gracias a Caddy tendremos algunas funcionalidades extra sin tener que realizar grandes esfuerzos de configuración:
- HTTPS automático.
- Soporte HTTP/2.
- Soporte HTTP/3.
- Soporte para respuestas HTTP 103 Early Hints que nos permiten optimizar la carga de nuestra aplicación.
Aunque para nosotros como desarrolladores lo mejor de todo es que es compatible con todas nuestras aplicaciones PHP ya que el servidor propiamente dicho integra el interprete de PHP, pero si queremos podemos ir un poco más allá y configurar el worker mode. Esto nos da un extra de flexibilidad y nos permite hacer una mejora progresiva de nuestras aplicaciones.
¿Cómo ejecutar WordPress sobre FrankenPHP?
Desde acceseo creemos que uno de los puntos más importantes es el enfoque puesto en el uso de contenedores, llevamos apostando por esta tecnología años y a cualquiera que haya trabajado con FPM sobre contenedores le será familiar la maraña de servicios, volúmenes y puertos a configurar para que el contenedor de PHP-FPM funcione con Apache o Nginx. Pues bien, FrankenPHP propone una solución muy simple en la que con 1 servicio sin dependencias tendremos acceso a todo con las ventajas de Caddy.
En acceseo durante el desarrollo de las aplicaciones usamos nuestras propias imágenes de httpd y php-fpm open source y configurado todo a través de docker compose. Por tanto partiremos de la base de estas imágenes de php-fpm para los ejemplos en esta configuración.
Tomando el dockerfile correspondiente a PHP 8.2 vamos a aplicar los siguientes cambios:
Simplemente modificamos la imagen que se usa como base por la de FrankenPHP y creamos con los permisos adecuados la carpeta /var/www/.local.
Una vez hecho esto hemos construido la imagen con el tag acceseo-local/php-fpm:8.2, ahora ya tenedremos todo listo para crear un archivo docker-compose.yml en el que configurar los servicios como el siguiente:
Puesto que nuestra imagen de php-fpm viene configurada con Xdebug, Composer y algunas extensiones más mantenemos todo esto aunque estemos trabajando con FrankenPHP. Podemos seguir haciendo debug, gestionando paquetes o utilizando las extensiones como hemos venido haciendo hasta ahora pese a haber realizado el cambio a FrankenPHP.
Llegados a este punto podemos añadir los archivos de WordPress en la carpeta donde tenemos el archivo docker-compose.yml y al navegar a https://localhost deberíamos ver el instalador de WordPress.
🎉 Tenemos nuestra primera web funcionando sobre FrankenPHP! 🧟
¿Cómo ejecutar Symfony sobre FrankenPHP?
Con la configuración que hemos creado para WordPress (o cualquier otro proyecto PHP al uso) podemos ejecutar nuestra aplicación Syfmony, pero si queremos sacar todo el partido a FrankenPHP debemos configurar el worker mode que nos promete interesantes mejoras de rendimiento.
Para ello solo tendremos que instalar mediante composer el paquete runtime/frankenphp-symfony y añadir las siguientes variables de entorno al contenedor en la sección environment del servicio en docker-compose.yml:
La primera indica a FrankenPHP cómo debe ejecutar la aplicación mientras que la segunda indica a la propia aplicación qué runtime ejecutar.
Una vez realizados estos cambios tendremos que regenerar el contenedor para que aplique las nuevas variables de entorno y ahora sí:
🎉 Tenemos nuestra aplicación Symfony funcionando sobre FrankenPHP con worker mode! 🧟
Conclusiones
Desde el equipo técnico de acceseo creemos que es una tecnología que todavía no está todo lo madura que necesitamos para que la DX sea la adecuada. Se puede utilizar y ofrece lo que promete pero no hay disponibles imágenes oficiales con distintas versiones de PHP por ejemplo.
Es cierto que configurando el worker mode con un proyecto de demo con Symfony muy sencillo hemos pasado de respuestas de 250-350ms a 150-250ms por tanto sí podemos apreciar el impacto en el rendimiento que menciona su creador y sin duda la configuración para docker compose se simplifica mucho respecto a la combinación de httpd y php-from que nosotros utilizamos.
Nosotros vamos a seguir muy de cerca todas las novedades de este proyecto tan interesante y para los que queráis profundizar más os dejamos algunos enlaces a continuación:
- https://speakerdeck.com/dunglas/frankenphp-a-modern-app-server-for-php-written-in-go
- https://speakerdeck.com/dunglas/frankenphp-a-modern-app-server-for-php-and-symfony-apps
- https://dunglas.dev/2022/10/frankenphp-the-modern-php-app-server-written-in-go/
- https://github.com/dunglas/frankenphp/tree/main/docs
2 comentarios en “Cómo ejecutar tu aplicación Symfony con FrankenPHP 🐘+🧟”
FrankenPHP esta en fase alpha, y su velocidad es menor que con PHP-FPM.
Benchmark:
https://github.com/symfony/symfony-docs/issues/17428#issuecomment-1339243991
Benchmark en modo Worker:
https://github.com/symfony/symfony-docs/issues/17428#issuecomment-1340822231
Ngx-php no es muy conocido, aunque es mucho más veterano. Es PHP embedido en Nginx, y actualmente el SAPI más rápido de PHP.
https://github.com/rryqszq4/ngx-php
Workerman es Node-js en PHP, y también muy rápido y poco conocido.
https://github.com/walkor/workerman
Adapterman es un runtime que usa Workerman, y que funciona con casi cualquier framework. El php-runtime de symfony solamente funciona con el Http Kernel de Symfony.
https://github.com/joanhey/AdapterMan
Hay muchos buenos projectos, pero parece que solamente miramos los que tienen más marketing, aunque sean inferiores.
Hola Joan, gracias por el comentario! No conocíamos Ngx-php así que le daremos un vistazo.
Como dices muchas veces hay proyectos que no tienen la repercusión que se merecen simplemente porque no llegan a tener tanta exposición, y en el caso de FrankenPHP precisamente es un proyecto que va a tener mucha exposición por los perfiles que hay involucrados así que seguro que todos vamos a seguir viendo un montón de publicaciones relacionadas.
Saludos, Christian.