12- Configuración de Nginx y MySQL para Laravel con Docker
Configuración de Nginx y MySQL para Laravel con Docker
Introducción
En este tutorial configuraremos los servicios de Nginx (servidor web) y MySQL (base de datos) para nuestro proyecto Laravel, completando así el entorno de desarrollo completo con Docker.
Paso 1: Detener Contenedores Existentes
Antes de modificar la configuración, debemos detener los contenedores activos:
# Verificar contenedores en ejecución docker ps # Detener todos los servicios (Docker Compose V2) docker compose down # Verificar que no queden contenedores docker ps
Paso 2: Crear Estructura de Directorios para Configuraciones
2.1 Crear carpetas para Nginx
# Crear directorios para configuraciones mkdir -p docker/nginx # Verificar estructura ls -la docker/
Estructura resultante:
laravel/ ├── docker/ │ └── nginx/ ├── Dockerfile ├── docker-compose.yml └── (archivos de Laravel)
Paso 3: Configurar Nginx
3.1 Crear archivo de configuración de Nginx
nano docker/nginx/app.conf3.2 Configuración actualizada de Nginx para Laravel
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; # Configuración de Laravel 11+ con Vite location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg|woff|woff2|ttf|eot)$ { expires 1y; add_header Cache-Control "public, immutable"; } location ~ \.php$ { fastcgi_pass app:9000; fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; include fastcgi_params; } location ~ /\.(?!well-known).* { deny all; } }
3.3 Puntos clave a verificar
| Configuración | Valor | Explicación |
|---|---|---|
root | /var/www/html/public | Directorio público de Laravel |
fastcgi_pass | app:9000 | Puerto de PHP-FPM (debe coincidir) |
listen | 80 | Puerto interno del contenedor |
Nota: La configuración de Nginx mostrada es un boilerplate oficial de Laravel. Puedes encontrarla en la documentación oficial de Laravel.
Paso 4: Actualizar docker-compose.yml
4.1 Agregar servicio de Nginx
Abrir el archivo:
nano docker-compose.ymlAgregar servicio Nginx:
nginx: image: nginx:alpine container_name: laravel_nginx restart: unless-stopped ports: - "8000:80" volumes: - ./:/var/www/html - ./docker/nginx:/etc/nginx/conf.d networks: - laravel depends_on: - app
4.2 Agregar servicio de MySQL
db: image: mysql:8.0 container_name: laravel_db restart: unless-stopped environment: MYSQL_DATABASE: ${DB_DATABASE:-laravel} MYSQL_USER: ${DB_USERNAME:-laravel} MYSQL_PASSWORD: ${DB_PASSWORD:-secret} MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD:-rootsecret} ports: - "3306:3306" volumes: - db_data:/var/lib/mysql networks: - laravel
4.3 Agregar volúmenes persistentes
volumes: db_data:
4.4 Configuración completa de networks
networks: laravel: driver: bridge
Paso 5: Configurar Variables de Entorno (.env)
5.1 Modificar el archivo .env de Laravel
nano .envConfiguración actualizada para 2024-2026:
APP_NAME=Laravel
APP_ENV=local
APP_KEY=
APP_DEBUG=true
APP_URL=http://localhost:8000
LOG_CHANNEL=stack
LOG_LEVEL=debug
# Configuración de base de datos
DB_CONNECTION=mysql
DB_HOST=db
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=laravel
DB_PASSWORD=secret
# Configuración de MySQL (variables para el contenedor)
MYSQL_DATABASE=laravel
MYSQL_USER=laravel
MYSQL_PASSWORD=secret
MYSQL_ROOT_PASSWORD=rootsecret
# Redis (opcional)
REDIS_HOST=redis
REDIS_PASSWORD=null
REDIS_PORT=6379
# Configuración de sesión
SESSION_DRIVER=database
SESSION_LIFETIME=120
SESSION_DOMAIN=localhost
# Configuración de cache
CACHE_DRIVER=file
QUEUE_CONNECTION=sync
# Configuración de mail (para desarrollo)
MAIL_MAILER=smtp
MAIL_HOST=mailpit
MAIL_PORT=1025
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
MAIL_FROM_ADDRESS="hello@example.com"
MAIL_FROM_NAME="${APP_NAME}"Paso 6: Dockerfile Actualizado (Opcional)
6.1 Instalar extensión PDO MySQL
Si aún no está instalada, agregar al Dockerfile:
RUN docker-php-ext-install pdo_mysql
Paso 7: Comandos para Levantar el Entorno
7.1 Levantar todos los servicios
# Levantar en segundo plano docker compose up -d # Verificar contenedores activos docker compose ps # Ver logs en tiempo real docker compose logs -f
7.2 Salida esperada
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES abc123def456 nginx:alpine "/docker-entrypoint.…" 2 minutes ago Up 2 minutes 0.0.0.0:8000->80/tcp laravel_nginx def456ghi789 mysql:8.0 "docker-entrypoint.s…" 2 minutes ago Up 2 minutes 0.0.0.0:3306->3306/tcp laravel_db ghi789jkl012 laravel-app "docker-php-entrypoi…" 2 minutes ago Up 2 minutes 9000/tcp laravel_app
Paso 8: Configuración Adicional (Recomendaciones 2024-2026)
✅ Servicio de Base de Datos (MySQL 8.0 vs 5.7)
MySQL 8.0 introduce cambios importantes:
# Para MySQL 8.0, agregar en el servicio db: command: --default-authentication-plugin=mysql_native_password
Versión recomendada: MySQL 8.0 o MariaDB 10.11+
✅ Alternativa: MariaDB (más ligero)
db: image: mariadb:10.11 container_name: laravel_db restart: unless-stopped environment: MYSQL_DATABASE: ${DB_DATABASE} MYSQL_USER: ${DB_USERNAME} MYSQL_PASSWORD: ${DB_PASSWORD} MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD} volumes: - db_data:/var/lib/mysql networks: - laravel
✅ Healthcheck para servicios
db: healthcheck: test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-p${DB_ROOT_PASSWORD}"] timeout: 20s retries: 10 interval: 10s
✅ Service de Mailpit (para pruebas de email)
mailpit: image: axllent/mailpit container_name: laravel_mailpit restart: unless-stopped ports: - "8025:8025" - "1025:1025" networks: - laravel
Paso 9: Verificación Final
9.1 Acceder a la aplicación
Abrir en navegador: http://localhost:8000
9.2 Verificar conexión a base de datos
# Ejecutar migraciones docker compose exec app php artisan migrate # Verificar conexión docker compose exec app php artisan db:show
9.3 Verificar logs
# Logs de Nginx docker compose logs nginx # Logs de MySQL docker compose logs db # Logs de la app docker compose logs app
Errores Comunes y Soluciones
| Error | Causa | Solución |
|---|---|---|
Connection refused | DB_HOST incorrecto | Usar db no localhost |
Access denied | Credenciales incorrectas | Verificar variables en .env |
No such file or directory | Ruta de Nginx mal configurada | Verificar root en app.conf |
Port already allocated | Puerto 8000 ocupado | Cambiar a 8001:80 |
SQLSTATE[HY000] [2002] | MySQL no listo | Esperar o usar depends_on con healthcheck |
FastCGI sent in stderr | PHP-FPM no disponible | Verificar fastcgi_pass apunta al servicio app |
Resumen del Flujo de Trabajo
Archivos Finales
Estructura completa del proyecto:
laravel/ ├── Dockerfile ├── docker-compose.yml ├── .env ├── docker/ │ └── nginx/ │ └── app.conf ├── app/ ├── bootstrap/ ├── config/ ├── database/ ├── public/ ├── resources/ ├── routes/ ├── storage/ ├── tests/ ├── vendor/ ├── composer.json ├── composer.lock └── .gitignore
¡Listo! Ahora tienes un entorno completo de desarrollo para Laravel con Nginx como servidor web y MySQL como base de datos, todo orquestado con Docker Compose V
Comentarios
Publicar un comentario