¿Cualquier aplicación PHP se puede dockerizar?

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.

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?

mchojrin

Por mchojrin

Ayudo a desarrolladores PHP a acceder mercados y clientes más sofisticados y exigentes

2 comentarios

  1. 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?

    1. 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:

      1. Un directorio montado en todos los contenedores
      2. Una tabla en la base de datos compartida
      3. Un almacenamiento tipo clave-valor (Memcached, Redis o similar)

      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.

¿Te quedó alguna duda? Publica aca tu pregunta

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.