Escenario real
Vamos a desplegar una aplicación PHP (por ejemplo, un sitio hecho con Laravel, Symfony o código propio) usando dos contenedores separados: uno con Nginx como servidor web y otro con PHP-FPM procesando los scripts. Esta separación es el patrón estándar en producción porque permite escalar Nginx y PHP de forma independiente.
Estructura del proyecto
mi-proyecto/
├── docker-compose.yml
├── .env
├── nginx/
│ └── default.conf
└── src/
└── public/
└── index.php
1. Archivo .env
Coloca los valores sensibles y configurables aquí:
APP_PORT=8080
PHP_VERSION=8.2
2. Configuración de Nginx
Guarda esto en nginx/default.conf. Nota cómo fastcgi_pass apunta al hostname app, que será el nombre del servicio PHP:
server {
listen 80;
server_name _;
root /var/www/html/public;
index index.php index.html;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_pass app:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
location ~ /\.ht {
deny all;
}
}
3. docker-compose.yml
services:
app:
image: php:${PHP_VERSION}-fpm-alpine
restart: unless-stopped
working_dir: /var/www/html
volumes:
- ./src:/var/www/html
networks:
- web
nginx:
image: nginx:1.27-alpine
restart: unless-stopped
depends_on:
- app
ports:
- "${APP_PORT}:80"
volumes:
- ./src:/var/www/html
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf:ro
networks:
- web
networks:
web:
4. Código PHP mínimo
En src/public/index.php pon algo simple para verificar:
<?php
echo "Hola desde PHP " . PHP_VERSION . " corriendo en Docker";
phpinfo();
5. Levantar el stack
docker compose up -d
docker compose ps
docker compose logs -f nginx
Abre tu navegador en http://localhost:8080 y deberías ver la salida de PHP. Si algo falla, revisa los logs del contenedor correspondiente.
Detalles importantes
- Ambos contenedores montan la misma carpeta
./srcen/var/www/html. Nginx necesita los archivos estáticos y PHP-FPM necesita los.php. - El mapeo de puerto
${APP_PORT}:80solo expone Nginx al host. PHP-FPM queda aislado dentro de la redweb, como debe ser. - Para producción real añade extensiones PHP necesarias (
pdo_mysql,opcache,gd) construyendo tu propia imagen con un Dockerfile basado enphp:8.2-fpm-alpine. - Si usas Laravel, recuerda correr
composer instally dar permisos astorage/ybootstrap/cache/.
Siguientes pasos
Este stack mínimo es la base para agregar una base de datos (MariaDB, PostgreSQL), un Redis para caché, un servicio de certificados TLS con Traefik o Caddy, y pipelines de despliegue automatizado. El patrón Nginx + PHP-FPM con Docker Compose es simple, poderoso y perfectamente válido para sitios en producción de tráfico medio.