5.3 · Docker para PHP: entornos reproducibles

Nivel 5 · Nivel pro & despliegue

5.3Docker para PHP: entornos reproducibles

Objetivo: contenerizar una aplicación PHP con Docker (Dockerfile, imágenes) y orquestar la pila (PHP/Nginx + MySQL + Redis) con Compose — reproducibilidad, aislamiento y facilidad de despliegue.
Tiempo estimado: 11 min · lectura autónoma · Si solo tienes 5 min: lee «Lo esencial en 30s» + el esquema.

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.

Error frecuente de interpretación: «Docker es solo para el despliegue — y los secretos pueden ir en el Dockerfile, es práctico». Doble error. Docker sirve desde el desarrollo (entorno idéntico en equipo, incorporación inmediata), no solo en producción. Y un secreto en el Dockerfile o la imagen queda legible para quien reciba la imagen: identificadores y claves pasan por el entorno al lanzar, nunca en la receta.
De la imagen al contenedor Corre igual en todas partes Dockerfile Receta: PHP +extensiones + Composerdocker build Construye laIMAGEN (modelo fijado)docker run Lanza unCONTENEDOR (instancia)Compose PHP + MySQL +Redis juntos
Corre igual en todas partes
Versión en texto del esquema (SEO / lectores de pantalla / traducción): 1) Dockerfile: Riad escribe la receta (imagen PHP, extensiones PDO y OPcache, dependencias Composer instaladas en la imagen). 2) Build: la imagen fija la app y su entorno. 3) Run: el contenedor corre idéntico en todo puesto. 4) Compose: PHP + MySQL lanzados juntos con un comando. Lección: el entorno viaja con el código — fin del «en mi casa funciona».

¿Lo sabía?

El «en mi máquina funciona» tiene un nombre de antipatrón: la diferencia de entorno. Docker la elimina haciendo viajar el entorno con el código.
El contenedor es la máquina que viaja.

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

  1. Escriba un Dockerfile: partir de una imagen PHP, instalar las extensiones necesarias, copiar el código, instalar las dependencias Composer.
  2. 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).
  3. Verifique que la aplicación corre en los contenedores y se comunica con su base (reproducibilidad del entorno).
  4. Aprecie los beneficios: aislamiento (versiones de PHP por proyecto sin conflicto), reproducibilidad (fin del «en mi casa funciona»), incorporación (un docker compose up).
Usted conteneriza una aplicación PHP con Docker (Dockerfile, imágenes) y orquesta la pila (PHP/Nginx + MySQL + Redis) con Compose — reproducibilidad, aislamiento y facilidad de despliegue.

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.

Prudencia: No ponga nunca secretos (contraseñas, claves, tokens) en el Dockerfile ni en la imagen: páselos por el entorno al lanzar. Una imagen compartida conserva todo su contenido — un secreto integrado queda legible.

✓ 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?

Lista de salida de la sección
  • Puedo explicar imagen vs contenedor en una frase.
  • Mi Dockerfile construye una imagen que corre.
  • Sé por qué los secretos no figuran en ella.
Autoevaluación 1-5: ¿mi imagen es reconstruible idéntica?¿un colega arrancaría mi pila en un comando?

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.

Comprueba tu comprensión

¿Qué problema resuelve Docker principalmente?

Recursos adicionales (opcional, para ir más allá)

Examen del nivel 5Preguntas inéditas y más difíciles para validar tus conocimientos