5.3Docker para PHP: entornos reproducibles
Lo esencial en 30 segundos
- Fin del «en mi máquina funciona»: el contenedor lleva la app con su entorno (versión PHP, extensiones, config) y corre idéntico en todas partes.
- Imagen → contenedor: el Dockerfile describe la receta (imagen PHP, extensiones, Composer), docker build fija la imagen, docker run lanza el contenedor.
- Compose para la pila: PHP + base + caché descritos en un archivo y lanzados juntos — incorporación en un comando.
Mini-caso hilado — Riad conteneriza en Constantina
La tienda optimizada de Riad corre perfectamente en su puesto en Constantina — pero falla en el de su colega (versión de PHP diferente, extensión PDO ausente, caso Windows/Linux). Escribe un Dockerfile: imagen PHP, extensiones instaladas en la imagen, dependencias Composer. Luego un archivo Compose con MySQL: un solo lanzamiento monta toda la pila. Continuación de los casos 5.1-5.2 — Riad hace su app reproducible en todas partes.
Continuación de los casos 5.1-5.2 — Riad pasa de «en mi casa funciona» a «igual en todas partes».
1. Contenerizar PHP: imagen y contenedor
Docker resuelve el «en mi máquina funciona» — particularmente frecuente en PHP (versiones, extensiones, configuración, sensibilidad a mayúsculas Windows/Linux) — empaquetando la aplicación con todo su entorno (la buena versión de PHP, las extensiones, la configuración, las dependencias) en un contenedor aislado y portable, que corre idéntico en todas partes: puesto, colega, servidor, nube. Conceptos: la imagen (modelo fijado de la app + entorno, definido por un Dockerfile — la receta: imagen PHP de base, extensiones, código copiado, dependencias Composer instaladas en la imagen, comando de arranque) y el contenedor (instancia en ejecución de una imagen). Se construye (docker build), se lanza (docker run). Riad ya no debate las versiones: el entorno viaja con el código.
Reflejo: todo lo específico de su puesto y ausente de la imagen es un futuro fallo en otra parte — la imagen debe contenerlo todo (extensiones incluidas).
2. Docker Compose y beneficios
Una aplicación PHP realista necesita varios contenedores que cooperan: PHP (con Nginx/Apache), la base (MySQL/MariaDB), eventualmente Redis. Docker Compose (docker-compose.yml) define todos estos contenedores y sus relaciones, lanzados juntos con un comando (docker compose up). Un solo archivo describe toda la pila, reproducible idéntica — y la incorporación se vuelve trivial: un nuevo desarrollador lanza un comando y obtiene todo el entorno, sin instalar ni configurar un pack local manualmente. Beneficios: reproducibilidad (idéntico en todas partes), aislamiento (proyectos con versiones de PHP diferentes cohabitan sin conflicto), portabilidad, facilidad de despliegue, incorporación rápida. Riad añade MySQL al Compose: su colega arranca en minutos.
Docker es un estándar del desarrollo moderno y una competencia transversal: las bases bastan para empezar, la orquestación avanzada vendrá según las necesidades.
3. La buena dosis para un desarrollador PHP
No hace falta volverse experto en infraestructura: apunte a las bases útiles — escribir un Dockerfile PHP simple, construir y lanzar, orquestar la pila con Compose, alinear la imagen con la producción para desarrollar en el mismo entorno que la puesta en línea. Para aprender PHP, un pack local basta; en cuanto se trabaja en equipo, se gestionan varios proyectos (versiones de PHP diferentes) o se prepara un despliegue, Docker paga. A evitar: apuntar a la orquestación avanzada antes que las bases, o contenerizar un minúsculo script de aprendizaje sin necesidad real. Riad mantiene su Dockerfile legible: cada instrucción comprendida vale más que una receta copiada.
El buen perfil: un desarrollador que conoce las bases de la explotación — autónomo, capaz no solo de codificar sino de entregar.
¿Lo sabía?
Misma imagen, mismo comportamiento — en todas partes.
🔎 Ejemplo concreto — El Dockerfile de Riad
La receta de la imagen PHP, legible y genérica.
FROM php:8.2-apache
RUN docker-php-ext-install pdo pdo_mysql opcache
COPY . /var/www/html/
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
RUN composer install --no-dev --optimize-autoloader
# docker compose up → PHP + MySQL juntos
Lectura: cada instrucción tiene un papel — base PHP, extensiones, código, dependencias, optimización prod.
Lección: las extensiones se instalan DENTRO de la imagen: fin de la diferencia entre puestos.
Vocabulario de la sección
- Docker
- Herramienta que empaqueta la app con su entorno en un contenedor portable.
Ejemplo sencillo: La tienda de Riad corre igual en Constantina y en casa de su colega.
Lo que no es: un pack local instalado a mano en cada puesto.
Reflejo: ¿mi app aún depende de mi puesto?
- Imagen
- Modelo fijado de la app + entorno, construido desde el Dockerfile.
Ejemplo sencillo: Riad construye una imagen versionada de cada entrega.
Lo que no es: el contenedor en curso de ejecución.
Reflejo: ¿puedo reconstruir esta imagen idéntica?
- Dockerfile
- Receta de construcción de la imagen (base PHP, extensiones, código, Composer).
Ejemplo sencillo: La receta legible de la tienda de Riad, extensiones incluidas.
Lo que no es: un script que instala PHP a mano en un servidor.
Reflejo: ¿cada instrucción está comprendida, no copiada?
- Contenedor
- Instancia en ejecución de una imagen, aislada y portable.
Ejemplo sencillo: Riad lanza un contenedor idéntico en dev y en preproducción.
Lo que no es: la imagen fijada ella misma.
Reflejo: ¿dev y prod lanzan la misma imagen?
- Docker Compose
- Archivo que describe varios contenedores lanzados juntos.
Ejemplo sencillo: PHP + MySQL de Riad arrancados con un solo comando.
Lo que no es: la orquestación avanzada de tipo Kubernetes.
Reflejo: ¿un nuevo dev arranca en un comando?
En la práctica — Contenerizar una aplicación PHP
- Escriba un Dockerfile: partir de una imagen PHP, instalar las extensiones necesarias, copiar el código, instalar las dependencias Composer.
- Orqueste la pila con Docker Compose: un docker-compose.yml que defina PHP (con Nginx/Apache), MySQL, y eventualmente Redis, lanzados juntos (docker compose up).
- Verifique que la aplicación corre en los contenedores y se comunica con su base (reproducibilidad del entorno).
- Aprecie los beneficios: aislamiento (versiones de PHP por proyecto sin conflicto), reproducibilidad (fin del «en mi casa funciona»), incorporación (un docker compose up).
Guion listo para decir — proponer Docker al equipo
«Nuestra tienda funciona en mi puesto pero no en otra parte: es un problema de entorno, no de código — versión de PHP, extensión ausente. Propongo un Dockerfile simple más un Compose con MySQL. Cada uno lanzará la misma imagen, y un recién llegado arrancará en un comando. Los secretos quedarán fuera de la imagen, pasados por el entorno.»
A decir en reunión de equipo para hacer adoptar la contenerización sin apuntar a la experiencia DevOps.
Modelo copiar-pegar — Dockerfile PHP + Compose genéricos
FROM php:8.2-apache
RUN docker-php-ext-install pdo pdo_mysql opcache
COPY . /var/www/html/
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
RUN composer install --no-dev --optimize-autoloader
# --- docker-compose.yml (pila genérica) ---
# services:
# app:
# build: .
# ports: ["8080:80"]
# environment:
# - DB_HOST=db
# db:
# image: mysql:8.0
# environment:
# - MYSQL_DATABASE=boutique
# - MYSQL_ROOT_PASSWORD_FILE=/run/secrets/db_root
Solo / presupuesto pequeño
Riad solo: un Dockerfile simple sin Compose basta — la imagen ya fija el entorno PHP.
TPE / equipo reducido
Compose PHP + MySQL: cada colega arranca la pila completa sin instalación manual.
PYME en Constantina
Riad comparte la imagen con el equipo en Constantina: todos prueban la misma versión, fin de las diferencias de puesto.
Equipo que empieza
Pareja: uno escribe el Dockerfile, el otro lo relee línea a línea; build probado en dos puestos antes de adoptar.
✓ Buenas prácticas
- Instalar las extensiones DENTRO de la imagen (fin de la diferencia entre puestos).
- Alinear la imagen con la producción (misma versión de PHP, mismas extensiones).
- Usar Docker Compose para orquestar la pila (incorporación rápida).
✗ Errores frecuentes
- Olvidar una extensión PHP en la imagen (falla en otra parte, no en casa).
- Poner secretos en el Dockerfile o la imagen (legibles por todos).
- Querer dominar la orquestación avanzada antes que las bases.
Puntos clave
- DOCKER (contenerización) empaqueta la aplicación CON su entorno (PHP, extensiones, config, dependencias) en un CONTENEDOR aislado y portable, que corre IDÉNTICO en todas partes — fin del «en mi máquina funciona» (frecuente en PHP).
- IMAGEN (modelo fijado, definido por un DOCKERFILE: imagen PHP + extensiones + código + Composer) → CONTENEDOR (instancia en ejecución).
- DOCKER COMPOSE (docker-compose.yml) orquesta la PILA PHP: varios contenedores (PHP/Nginx + MySQL + Redis) lanzados juntos (`docker compose up`).
- Beneficios: REPRODUCIBILIDAD, AISLAMIENTO (versiones de PHP por proyecto sin conflicto), portabilidad, despliegue fácil, incorporación rápida. Estándar moderno (transversal DevOps).
Reto 48h — aplique mañana
Escriba el Dockerfile de su app (modelo anterior) y láncela en contenedor: ¿responde igual que en su puesto?
- Puedo explicar imagen vs contenedor en una frase.
- Mi Dockerfile construye una imagen que corre.
- Sé por qué los secretos no figuran en ella.
Preguntas frecuentes
¿Qué aporta Docker a un desarrollador PHP, y es necesario cuando un pack local ya funciona?
Un pack local es perfecto para empezar: simple, operativo en minutos — no se complique al inicio. Pero sus límites aparecen en contexto profesional: el entorno puede diferir de la producción (versiones, extensiones, config — el clásico «funciona en local pero no en línea»), gestionar varios proyectos con versiones de PHP diferentes es complicado, y el entorno no es fácilmente compartible. Docker aporta la reproducibilidad (mismo entorno en todas partes, incluida la producción), el aislamiento (cada proyecto su contenedor, sin conflicto de versiones), la portabilidad y una incorporación en un comando. Casi imprescindible en desarrollo profesional — a aprender cuando se trabaja en equipo o se prepara un despliegue.
Docker, despliegue, CI/CD... ¿un desarrollador PHP debe volverse un experto DevOps?
No, no un experto — pero conocer las bases lo cambia todo: autonomía (poner su trabajo en producción sin depender de otros), empleabilidad (las ofertas piden Docker/despliegue/CI-CD), mejor colaboración (apps fáciles de desplegar), visión completa del ciclo. Apunte a las bases: contenerizar y Compose (no la orquestación avanzada), desplegar en un alojamiento simple, un pipeline CI/CD simple, secretos y config en variables de entorno, nociones de logs y HTTPS. El buen perfil: un desarrollador que conoce las bases de la explotación — capaz no solo de codificar sino de entregar.
¿Qué problema resuelve Docker principalmente?