10-Configuración de Docker Compose para Laravel
Configuración de Docker Compose para Laravel
¡Exacto! Pero con un matiz importante sobre cómo se obtienen esas imágenes:
| Recurso | ¿Crea imágenes? | ¿Cómo lo hace? | ¿Qué imágenes? |
|---|---|---|---|
| Dockerfile | ✅ Sí | Construye (build) desde cero siguiendo tus instrucciones. | Solo la de PHP (laravel-app). |
| docker-compose.yml | ✅ Sí (indirectamente) | Orquesta el proceso. Para app construye usando tu Dockerfile. Para nginx y db descarga (pull) las imágenes ya hechas de internet (Docker Hub). | Las 3: PHP (construida), Nginx y MySQL (descargadas). |
Además de "crear imágenes", docker-compose hace 3 cosas clave:
Las une en una red (
laravel): Para que puedan "escucharse" entre sí. Por ejemplo, Nginx puede hablar con PHP-FPM, y PHP puede conectarse a la base de datos MySQL usando el nombre del servicio (db) como si fuera una dirección.Crea los contenedores: Toma esas 3 imágenes y las convierte en 3 procesos en ejecución.
Gestiona el ciclo de vida: Las levanta, las reinicia si fallan, y comparte archivos (volúmenes) entre tu PC y los contenedores.
En resumen:
Dockerfile → Construye 1 imagen (PHP).
docker-compose → Construye 1 (PHP) + Descarga 2 (Nginx, MySQL) + Las conecta en red + Las ejecuta.
Por eso al final ves 3 imágenes y 3 contenedores funcionando como un solo equipo.
Dockerfile (la "receta")
Sirve para construir una única imagen.
Define qué lleva dentro un solo contenedor: sistema operativo, extensiones de PHP, Composer, usuario, etc.
Es como los planos de una casa. Solo construyes un entorno (en tu caso, el contenedor PHP-FPM).
⚙️ docker-compose.yml (el "plano de obra completa")
Sirve para orquestar y levantar múltiples contenedores a la vez.
Define cómo se relacionan varios servicios: el contenedor PHP (hecho con tu Dockerfile), el servidor web (Nginx), la base de datos (MySQL) y Redis.
Configura redes, volúmenes (para compartir archivos), puertos y orden de arranque.
▶️ Diferencia práctica:
Dockerfile → haces
docker buildy obtienes 1 contenedor (PHP).docker-compose.yml → haces
docker compose upy obtienes todo el ecosistema (PHP + Nginx + MySQL + Redis) funcionando al mismo tiempo, listo para ejecutar Laravel.
En resumen: el Dockerfile construye la pieza, y el docker-compose las une y las pone a funcionar en equipo.
Introducción
En este tutorial crearemos el archivo docker-compose.yml para orquestar nuestros contenedores. Este archivo define todos los servicios necesarios para ejecutar una aplicación Laravel en un entorno Dockerizado.
Paso 1: Corregir Errores del Dockerfile
Antes de continuar, debemos corregir un error en el Dockerfile. El comando apt-get necesita el signo - correctamente:
# ❌ Incorrecto
RUN apt-get update && apt-get install -y curl
# ✅ Correcto
RUN apt-get update && apt-get install -y curlPaso 2: Verificar el UID del Usuario
Necesitamos saber el UID (User ID) de nuestro usuario actual para mapearlo correctamente:
id -uEjemplo de salida:
1000Paso 3: Crear el Archivo docker-compose.yml
3.1 Crear y editar el archivo
nano docker-compose.yml3.2 Versión actualizada (2024-2026)
Actualmente, la versión 3 es la estándar, pero Docker Compose V2 acepta tanto version como la sintaxis sin versión:
# Formato actual con versión (compatible)
version: '3.8'
# Formato moderno sin versión (recomendado)
# services:Paso 4: Estructura Completa del docker-compose.yml
4.1 Configuración del servicio principal (app)
version: '3.8'
services:
app:
build:
context: .
dockerfile: Dockerfile
args:
USERNAME: ${USER:-laravel}
USERID: ${UID:-1000}
image: laravel-app
container_name: laravel_app
restart: unless-stopped
working_dir: /var/www/html
volumes:
- ./:/var/www/html
networks:
- laravel
depends_on:
- db
- redis
environment:
- APP_ENV=local
- APP_DEBUG=true4.2 Configuración de redes
networks:
laravel:
driver: bridgePaso 5: Configuración Avanzada con Servicios Adicionales
5.1 Servicio de Base de Datos (MySQL/MariaDB)
db:
image: mysql:8.0
container_name: laravel_db
restart: unless-stopped
environment:
MYSQL_DATABASE: laravel
MYSQL_USER: laravel
MYSQL_PASSWORD: secret
MYSQL_ROOT_PASSWORD: rootsecret
volumes:
- db_data:/var/lib/mysql
ports:
- "3306:3306"
networks:
- laravel5.2 Servicio de Base de Datos (PostgreSQL)
db:
image: postgres:15
container_name: laravel_db
restart: unless-stopped
environment:
POSTGRES_DB: laravel
POSTGRES_USER: laravel
POSTGRES_PASSWORD: secret
volumes:
- db_data:/var/lib/postgresql/data
ports:
- "5432:5432"
networks:
- laravel5.3 Servicio de Redis (Caché/Colas)
redis:
image: redis:7-alpine
container_name: laravel_redis
restart: unless-stopped
ports:
- "6379:6379"
networks:
- laravel5.4 Servicio Nginx (Servidor Web)
nginx:
image: nginx:alpine
container_name: laravel_nginx
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- ./:/var/www/html
- ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf
depends_on:
- app
networks:
- laravel5.5 Servicio PHPMyAdmin (Opcional)
phpmyadmin:
image: phpmyadmin/phpmyadmin
container_name: laravel_phpmyadmin
restart: unless-stopped
environment:
PMA_HOST: db
PMA_PORT: 3306
UPLOAD_LIMIT: 100M
ports:
- "8080:80"
networks:
- laravelPaso 6: Archivo de Variables de Entorno (.env)
Crear un archivo .env para manejar variables sensibles:
nano .envContenido:
# Usuario y UID
USER=laravel
UID=1000
# Base de datos
DB_CONNECTION=mysql
DB_HOST=db
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=laravel
DB_PASSWORD=secret
# Redis
REDIS_HOST=redis
REDIS_PASSWORD=null
REDIS_PORT=6379Paso 7: Configuración de Nginx (Opcional)
Crear directorio y archivo de configuración:
mkdir -p docker/nginx
nano docker/nginx/default.confContenido:
server {
listen 80;
server_name localhost;
root /var/www/html/public;
add_header X-Frame-Options "SAMEORIGIN";
add_header X-Content-Type-Options "nosniff";
index index.php index.html;
charset utf-8;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }
error_page 404 /index.php;
location ~ \.php$ {
fastcgi_pass app:9000;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
include fastcgi_params;
}
location ~ /\.(?!well-known).* {
deny all;
}
}Paso 8: Actualizaciones y Buenas Prácticas (2024-2026)
✅ Docker Compose V2
El comando con guión está obsoleto:
# ❌ Antes (obsoleto)
docker-compose up -d
# ✅ Ahora (recomendado)
docker compose up -d✅ Sintaxis sin "version"
Las nuevas versiones de Docker Compose permiten omitir version:
# Formato moderno (sin version)
services:
app:
# ...✅ Health Checks
Agregar verificaciones de salud para mejorar la confiabilidad:
db:
image: mysql:8.0
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
timeout: 20s
retries: 10
interval: 10s✅ Replicas y Escalado
Para desarrollo local con escalado:
app:
deploy:
replicas: 2Paso 9: Comandos Útiles
9.1 Levantar los servicios
docker compose up -d9.2 Verificar logs
docker compose logs app9.3 Detener servicios
docker compose down9.4 Reconstruir con caché limpia
docker compose build --no-cache9.5 Ejecutar comandos dentro del contenedor
docker compose exec app composer install
docker compose exec app php artisan migrate
docker compose exec app php artisan key:generateResumen: Estructura de Archivos
laravel/
├── Dockerfile
├── docker-compose.yml
├── .env
├── docker/
│ └── nginx/
│ └── default.conf
└── src/
└── (código fuente de Laravel)Errores Comunes y Soluciones
| Error | Causa | Solución |
|---|---|---|
permission denied | UID mapeado incorrecto | Verificar id -u y ajustar variable |
port already allocated | Puerto en uso | Cambiar puerto en ports: |
Cannot connect to db | Red no configurada | Verificar networks: |
No such service | Versión antigua de Compose | Actualizar Docker |
¡Listo! Ahora tienes un archivo docker-compose.yml completo y modernizado para tu proyecto Laravel. En el siguiente paso podrás probar la configuración y comenzar a instalar Laravel dentro del contenedor.
RESUMEN RÁPIDO DE COMANDOS
Obtén el ID del contenedor que quieres eliminar:
docker ps -a
Verás una lista como esta:
CONTAINER ID IMAGE COMMAND CREATED STATUS abc123def456 laravel-app "php-fpm" 5 minutes ago Exited (0)
Elimina usando ese ID:
docker rm abc123def456
| Acción | Comando |
|---|---|
| Crear imagen | docker build -t nombre:tag . |
| Ver imágenes | docker images |
| Eliminar imagen | docker rmi nombre:tag |
| Crear contenedor | docker run -d --name nombre imagen |
| Ver contenedores activos | docker ps |
| Ver todos los contenedores | docker ps -a |
| Detener contenedor | docker stop nombre |
| Eliminar contenedor | docker rm nombre |
| Eliminar contenedor (forzado) | docker rm -f nombre |
| Eliminar todo lo no usado | docker system prune -a |
Comentarios
Publicar un comentario