Docker y PHP: contenerización de aplicaciones de la A a la Z
La contenerización de aplicaciones PHP con Docker se ha convertido en el estándar del desarrollo web moderno. Ya sea que esté creando una simple página de aterrizaje o una aplicación corporativa compleja, Docker garantiza la uniformidad del entorno en todas las etapas: desde el desarrollo local hasta la producción. En este artículo, analizaremos todas las etapas de creación de una infraestructura Docker para una aplicación PHP, desde un Dockerfile básico hasta una pila completa con Nginx y MySQL.
Por qué Docker es importante para el desarrollador PHP
El desarrollo tradicional de PHP a menudo se enfrenta al problema de "en mi máquina funciona". Diferentes versiones de PHP, extensiones, configuraciones del servidor: todo esto genera conflictos. Docker resuelve este problema de una vez por todas:
- Aislamiento del entorno — cada aplicación tiene su propio conjunto de dependencias
- Reproducibilidad — el mismo entorno en todas las máquinas
- Escalabilidad — fácil agregar nuevos servicios (Redis, Elasticsearch)
- Integración CI/CD — los contenedores son ideales para pipelines
Pasemos de la teoría a la práctica y creemos un entorno Docker completo para una aplicación PHP.
Creación de un Dockerfile básico para PHP
Empecemos con lo más importante: el Dockerfile. Esta es la instrucción para construir la imagen de su aplicación PHP. Aquí tiene una configuración óptima para una aplicación lista para producción:
# Usamos la imagen oficial de PHP con FPMFROM php:8.2-fpm-alpine
# Instalación de dependencias del sistemaRUN apk add --no-cache \ git \ unzip \ libpq-dev \ libzip-dev \ && docker-php-ext-install \ pdo_mysql \ zip \ opcache
# Instalación de ComposerCOPY --from=composer:latest /usr/bin/composer /usr/bin/composer
# Configuración de OPcache para producciónRUN { \ echo 'opcache.memory_consumption=128'; \ echo 'opcache.interned_strings_buffer=8'; \ echo 'opcache.max_accelerated_files=4000'; \ echo 'opcache.revalidate_freq=2'; \ echo 'opcache.fast_shutdown=1'; \ echo 'opcache.enable_cli=1'; \} > /usr/local/etc/php/conf.d/opcache.ini
# Copiamos los archivos de la aplicaciónWORKDIR /var/www/htmlCOPY . .
# Establecemos permisosRUN chown -R www-data:www-data /var/www/html \ && chmod -R 755 storage bootstrap/cache
# Iniciamos PHP-FPMCMD ["php-fpm"]
EXPOSE 9000Este Dockerfile utiliza Alpine Linux, una imagen mínima que reduce significativamente el tamaño del contenedor final. Instalamos solo las extensiones necesarias: pdo_mysql para trabajar con la base de datos y zip para Composer.
Construcción y ejecución del contenedor
# Construcción de la imagendocker build -t my-php-app .
# Ejecución del contenedordocker run -d -p 9000:9000 --name php-app my-php-appPila completa con Nginx y MySQL mediante docker-compose
Una aplicación real rara vez consta de un solo contenedor PHP. Necesitamos un servidor web y una base de datos. Aquí es donde docker-compose viene al rescate: una herramienta para orquestar múltiples contenedores.
Creemos el archivo docker-compose.yml:
version: '3.8'
services: # Servicio PHP-FPM app: build: context: . dockerfile: Dockerfile container_name: php-app volumes: - ./:/var/www/html networks: - app-network
# Servidor web Nginx nginx: image: nginx:alpine container_name: php-nginx ports: - "8080:80" volumes: - ./:/var/www/html - ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf depends_on: - app networks: - app-network
# Base de datos MySQL db: image: mysql:8.0 container_name: php-mysql ports: - "3306:3306" environment: MYSQL_ROOT_PASSWORD: root_password MYSQL_DATABASE: app_database MYSQL_USER: app_user MYSQL_