¿Vale la pena Dockerizar tu php?
Permitime contestarte con un ejercicio.
Imaginate esta situación:
Venís trabajando sin descanso en una aplicación muy importante para entregar a un cliente.
Vas a buen ritmo, vas a llegar a la entrega sin mucho problema.
De pronto, te aparece la notificación de actualizar el sistema operativo y pensás: «Y… la verdad que no estaría mal… no puedo seguir toda la vida con la 1.0…».
Le das aceptar y, luego de unos minutos, cuando todo terminó te das cuenta de que la aplicación que andaba perfecta dejó de funcionar.
¿Eh?
¿Cómo puede ser?
Así como instintivamente tirás un php -v
y comprobás que de 7.4
saltaste sin escalas a 8.1
… y las cosas ya no son como antes.
¡Qué problema! Menos mal que es una situación hipotética ¿no?
Pues… no tanto. Esta historia es una adaptación libre de esta conversación que leí recientemente:
«se me actualizo php a la version 8 en Manjaro, y por ende se me descuadró todo, qué tengo que cambiar en el httpd.conf para que me funcione php8«
«Soy usuario de manjaro y me pasó lo mismo. Pero por suerte tenia dockerizado mis proyectos y no sufrí demasiado, deberías considerarlo«
Yo diría que suerte habría sido no tener que enfrentarse al problema.
Tener tus proyectos php dockerizados no es suerte, es una decisión.
Tweet
Una decisión que en algún momento este desarrollador tomó y que también deberías, al menos, evaluar.
Es un caso muy similar al que analizo acá.
Pensando un poco en esto empecé a preguntarme: ¿Cualquier aplicación php se puede dockerizar?
Qué significa dockerizar una aplicación PHP
Cuando se habla de dockerizar (me encanta este verbo) una aplicación, se hace referencia a hacer las adaptaciones necesarias para poder correrla sobre contenedores docker, tanto en un etorno de desarrollo como en uno de producción.
Estos ajustes dependen en gran medida de la naturaleza de la aplicación pero, a rasgos generales, se trata de:
- Crear un Dockerfile (O al menos seleccionar una imagen pre-existente que sea compatible con las necesidades de la aplicación)
- Cambiar, si las hubiera, referencias a
localhost
por otras que apunten a servicios dentro del ecosistema de docker - Crear una configuración de inicio de los servicios (Ya sea a través de Makefiles o similar o, mejor aún, a través de un archivo docker-compose)
En principio creo que no hay mucho más, pero si te parece que me olvidé de algo importante, por favor dejame un comentario abajo.
Qué se necesita para dockerizar una aplicación PHP
Para dockerizar una aplicación PHP se necesita, primero que nada, contar, tanto en local como en producción, con el motor y el cliente de docker.
Si se pretende usar docker-compose, también deberá estar presente en ambos lados.
Más allá de eso, es conveniente contar con un buen IDE, aunque no es imprescindible.
Técnicamente no se necesita nada más. Claro que saber lo que se está haciendo ayuda mucho.
Cómo dockerizar una aplicación PHP
Teniendo todo en su lugar el proceso es simple, aunque, dependiendo de la aplicación, puede ser más laborioso que en otros casos.
Relevamiento
Lo primero es entender cuáles son las dependencias:
- ¿Qué versión de PHP usás en producción?
- ¿Qué extensiones de PHP necesitás instaladas y habilitadas?
- ¿Qué otros servicios de infraestructura se usan con tu aplicación? ¿MySQL? ¿Redis?
- ¿Qué versiones?
- ¿Cómo está la configuración del webserver?
- ¿Cómo está la configuración de PHP?
- ¿Qué permisos sobre archivos necesita la aplicación para funcionar?
Con las respuestasa a estas preguntas podrás darte una idea de lo que requerirás en tu imagen docker.
Instalación de las herramientas
Si no las tienes disponibles, el próximo paso será instalar las herramientas necesarias (docker engine, docker client y docker-compose al menos).
Adaptación de la aplicación
Luego deberás preparar la aplicación:
- Reemplazar referencias a servicios externos (Bases de datos, colas de mensajes, etc…) de IPs o nombres conocidos en el host a nombres conocidos dentro de la red de Docker
- Reemplazar rutas absolutas por relativas
- Reemplazar enlaces simbólicos por archivos concretos
Creación de los archivos de Docker
Es muy probable que tu aplicación tenga algunos requisitos específicos que no encuentres en una de las imágenes disponibles en el dockerhub. No te preocupes, siempre podés tomar una imagen lo más parecida posible a tus necesidades para usar como base y agregar tus cambios particulares.
Si el sistema es suficientemente complejo (si requiere de otros componentes de infraestructura), es conveniente definir también un archivo docker-compose.yml
para mayor comodidad.
Pruebas y ajustes
Una vez hayas pasado por los pasos anteriores será cuestión de probar la aplicación y validar que todo funciona.
Los comandos exactos dependerán de cómo hayas armado los archivos de configuración, pero será algo así como:
docker build . -t mi_php docker run -it mi_php
O, si usas docker-compose:
docker-compose up --build
Una vez estén levantados los servicios podrás entrar a http://localhost:8000
(Asumo que el puerto 8000 está mapeado al 80 en el contenedor) y ya podrás verificar que toda la aplicación funciona.
Por qué dockerizar tus aplicaciones php
Si te parece mucho trabajo, tenés razón, dockerizar una aplicación PHP puede ser molesto, especialmente cuando lo tienes que hacer por primera vez pero, si queda bien, es muy probable que no tengas que volver a hacerlo por mucho tiempo y, a la vez, tu aplicación quedará blindada ante cambios en el ambiente, tanto local como de producción.
De pronto no se ve tan mal, ¿no?
- Cómo agregar una página de error 500 en un proyecto PHP - 31/10/2024
- ¿Cuántos contenedoresnecesita tu php? - 28/10/2024
- Cuál es el mejor framework PHP para hacer APIs REST - 25/10/2024
Buen artículo. Me surge una duda, tenemos una aplicación php que maneja sesiones. Si la dockerizamos y la ponemos en varios dockers diferentes, teniendo un proxy que haga balanceo: ¿Cómo puedo hacer que las sesiones sigan funcionando?
Hola Fabián:
Gracias por tu pregunta. Muy interesante el caso que planteás. La raíz de todo el problema es la forma en que PHP maneja las sesiones. Por defecto, los datos de las sesiones se almacenan en un directorio local.
La solución pasa por cambiar esto por un soporte compartido.
Las opciones son varias:
De los tres que nombré el que más me gusta es el último, aunque el segundo no está tan mal tampoco. El primero no lo recomiendo porque nuevamente dependerá de que los contenedores estén físicamente ejecutando en un mismo servidor (O que tengan un directorio compartido a través de la red… probablemente no vaya a ser lo mejor en términos de eficiencia).
Una solución interesante sería agregar un nuevo contenedor al setup para el clave-valor y luego, en los contenedores que ejecutan php cambiar la confguración session.save_handler.
Si tenés una muy buena razón para hacerlo, podrías implementar tu propio mecanismo de manejo de sesiones a través de la interface SessionHandlerInterface aunque me parece un poco demasiado para la mayoría de los casos.
En rigor de verdad, este problema no es específico de Docker. Lo mismo pasaría si la infraestructura no estuviese dockerizada, aunque es cierto que resolverlo dentro de Docker es algo más sencillo.
Espero haberte ayudado, cualquier duda comentame.