La Infraestructura Detrás de la Plataforma
Construir una plataforma como Play The Event no significa solo escribir código aplicativo: significa también diseñar una infraestructura que garantice fiabilidad, reproducibilidad y facilidad de despliegue. Desde el entorno de desarrollo local hasta la VPS de producción, cada componente de infraestructura ha sido pensado para reducir los tiempos de despliegue, minimizar los errores manuales y garantizar que los servicios estén siempre disponibles.
Este artículo explora completamente la pila DevOps de Play The Event: desde el contenido con Docker Compose presenta configuración Nginx con SSL, desde servicios systemd hasta scripts de automatización, pasando por la gestión de migraciones de bases de datos y el caché de Redis.
Qué Encontrarás en Este Artículo
- Docker Compose para el entorno de desarrollo con MySQL, Redis, phpMyAdmin y Redis Commander
- Nginx como reverse proxy con SSL Let's Encrypt, rate limiting y security headers
- Servicios systemd para arranque automático de backend y frontend
- 18+ scripts Bash para despliegue, arranque, parada, reinicio y mantenimiento
- 199 migraciones Flyway para la evolución del sistema MySQL
- Redis con configuración de 256 MB y política allkeys-lru
- Gestión de logs y monitorización de la salud de los servicios
Docker Compose: El Entorno de Desarrollo
El entorno de desarrollo de Play The Event está completamente containerizado mediante Docker Compose. Cuatro servicios orquestados garantizan que cada desarrollador pueda arrancar todo el stack con un solo comando, sin preocuparse de instalar y configurar manualmente MySQL, Redis o las herramientas de administración.
version: '3.8'
services:
# MySQL 8.4.3 - Database principale
mysql:
image: mysql:8.4.3
container_name: management-events-mysql
restart: unless-stopped
environment:
MYSQL_DATABASE: management_events_db
MYSQL_USER: events_user
TZ: Europe/Rome
ports:
- "3306:3306"
volumes:
- mysql_data:/var/lib/mysql
- ./backend/src/main/resources/db/init:/docker-entrypoint-initdb.d
command:
- --character-set-server=utf8mb4
- --collation-server=utf8mb4_unicode_ci
- --max_connections=200
- --innodb_buffer_pool_size=1G
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 10s
timeout: 5s
retries: 5
# Redis 7.4.1 - Cache e sessioni
redis:
image: redis:7.4.1-alpine
container_name: management-events-redis
restart: unless-stopped
ports:
- "6379:6379"
volumes:
- redis_data:/data
command: >
redis-server --appendonly yes
--maxmemory 256mb
--maxmemory-policy allkeys-lru
# phpMyAdmin - Gestione database via web
phpmyadmin:
image: phpmyadmin:5.2
container_name: management-events-phpmyadmin
ports:
- "8081:80"
depends_on:
mysql:
condition: service_healthy
# Redis Commander - Gestione cache via web
redis-commander:
image: rediscommander/redis-commander:latest
container_name: management-events-redis-commander
environment:
REDIS_HOSTS: local:redis:6379
ports:
- "8082:8081"
depends_on:
redis:
condition: service_healthy
Algunos aspectos clave de la configuración de Docker:
- Health checks: Tanto MySQL como Redis tienen health checks integrados. Los servicios dependientes (phpMyAdmin, Redis Commander) esperan a que los servicios base estén listos antes de arrancar
- Volúmenes persistentes:
mysql_datayredis_datagarantizan que los datos sobrevivan al reinicio de los contenedores - MySQL optimizado:
utf8mb4para soporte Unicode completo,innodb_buffer_pool_size=1Gpara rendimiento óptimo, hasta 200 conexiones simultáneas - Redis con AOF:
appendonly yesHabilite la persistencia del disco. Políticaallkeys-lruEvite la pérdida de memoria eliminando las publicaciones utilizadas menos recientemente
Puertos de los Servicios de Desarrollo
- 3306 - MySQL 8.4.3 (base de datos principal)
- 6379 - Redis 7.4.1 (caché y sesiones)
- 8080 - Backend Spring Boot (API REST)
- 4200 - Frontend Angular (servidor de desarrollo)
- 8081 - phpMyAdmin (gestión de base de datos)
- 8082 - Redis Commander (gestión de caché)
Nginx: Proxy inverso con SSL
En producción, Nginx actúa como reverse proxy delante de todos los servicios de Play The Event. Gestiona la terminación SSL, el enrutamiento de peticiones, la compresión gzip, el almacenamiento en caché de assets estáticos y la protección mediante rate limiting.
# Upstream per il backend Spring Boot
upstream backend_api {
server localhost:8080 fail_timeout=5s max_fails=3;
keepalive 32;
}
# Rate limiting zones
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=100r/m;
limit_req_zone $binary_remote_addr zone=login_limit:10m rate=10r/m;
server {
listen 443 ssl http2;
server_name playtheevent.com www.playtheevent.com;
# SSL Let's Encrypt
ssl_certificate /etc/letsencrypt/live/playtheevent.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/playtheevent.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
# Security headers
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
# Gzip compression
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_comp_level 6;
gzip_types text/plain text/css application/json
application/javascript text/xml image/svg+xml;
# Backend API con rate limiting
location /api/ {
limit_req zone=api_limit burst=20 nodelay;
proxy_pass http://backend_api;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# Rate limiting stretto per login
location /api/auth/login {
limit_req zone=login_limit burst=5 nodelay;
proxy_pass http://backend_api;
}
# Frontend Angular (SSR o static)
location / {
try_files $uri $uri/ /index.html;
}
# Asset statici con cache lunga
location ~* \.(js|css|png|jpg|svg|woff2)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
}
Seguridad a Nivel de Red
La configuración de Nginx implementa diferentes estrategias de protección:
- Rate limiting en dos niveles: Las APIs generales están limitadas a 100 peticiones por minuto por IP, mientras que los endpoints de autenticación tienen un límite mucho más restrictivo de 10 peticiones por minuto, con respuesta HTTP 429 en caso de superación
- SSL con Let's Encrypt: Certificados gratuitos con renovación automática a través de Certbot. el guion
setup-ssl.shautomatiza la verificación de DNS, la instalación de Certbot y la generación de certificados - Security headers: Protección contra clickjacking (
X-Frame-Options), MIME sniffing (X-Content-Type-Options) y XSS (X-XSS-Protection) - Bloqueo de archivos sensibles: Cualquier petición a archivos que empiecen por
.(como.env,.git) se bloquea automáticamente
Endpoint de Health Check
Nginx expone un endpoint /health dedicado a la monitorización externa. Este endpoint
devuelve una respuesta simple sin tocar el backend, permitiendo a los sistemas de monitorización
verificar que el reverse proxy está activo.
# Health check endpoint (risposta diretta da Nginx)
location /health {
access_log off;
return 200 "healthy\n";
add_header Content-Type text/plain;
}
# Nginx status per monitoraggio (solo localhost)
location /nginx_status {
stub_status on;
access_log off;
allow 127.0.0.1;
deny all;
}
Systemd: Servicios con Arranque Automático
El backend Spring Boot y el frontend Angular se gestionan como servicios systemd en la VPS Ubuntu 24.04. Esto garantiza que los servicios se reinicien automáticamente tras un fallo o un reinicio del servidor.
[Unit]
Description=Play the Event - Backend Spring Boot API
After=network.target mysql.service
Wants=mysql.service
[Service]
Type=simple
User=federicocalo
WorkingDirectory=/home/ubuntu/managementevents/backend
# Environment
Environment="JAVA_HOME=/usr/lib/jvm/java-21-openjdk-amd64"
Environment="SPRING_PROFILES_ACTIVE=prod"
EnvironmentFile=/home/ubuntu/managementevents/backend/.env.prod
# Esecuzione con JAR precompilato
ExecStart=/usr/bin/java -jar target/management-events-backend.jar
# Restart policy
Restart=on-failure
RestartSec=10s
StartLimitInterval=5min
StartLimitBurst=3
# Resource limits
LimitNOFILE=65536
LimitNPROC=4096
# Logging
StandardOutput=journal
StandardError=journal
SyslogIdentifier=play-the-event-backend
# Security
NoNewPrivileges=true
PrivateTmp=true
# Graceful shutdown
TimeoutStopSec=30s
KillMode=mixed
KillSignal=SIGTERM
[Install]
WantedBy=multi-user.target
[Unit]
Description=Play the Event - Frontend Angular
After=network.target
[Service]
Type=simple
User=federicocalo
WorkingDirectory=/home/ubuntu/managementevents/frontend
# Environment
Environment="NODE_ENV=production"
# Angular serve (SSR o static)
ExecStart=/usr/bin/npm start
# Restart policy
Restart=on-failure
RestartSec=10s
StartLimitInterval=5min
StartLimitBurst=3
# Logging
StandardOutput=journal
StandardError=journal
SyslogIdentifier=play-the-event-frontend
# Security
NoNewPrivileges=true
PrivateTmp=true
# Graceful shutdown
TimeoutStopSec=15s
KillMode=mixed
KillSignal=SIGTERM
[Install]
WantedBy=multi-user.target
Aspectos importantes de la configuración de systemd:
- Dependencias: El backend declara
After=mysql.serviceyWants=mysql.service, asegurando que MySQL se inicie antes de la aplicación Spring Boot - Reinicio automático:
Restart=on-failureconRestartSec=10sReinicia automáticamente la bolsa después de una pasada, con un límite de 3 intentos en 5 minutos para evitar un sinfín de preocupaciones. - Variables de entorno: Las configuraciones sensibles se cargan desde
.env.prodmedianteEnvironmentFile, manteniendo las credenciales fuera del código fuente - Seguridad:
NoNewPrivileges=trueimpide la escalada de privilegios,PrivateTmp=trueaísla el directorio temporal del servicio - Desfile elegante:
KillSignal=SIGTERMconKillMode=mixedPrimero envíe una señal de terminación al proceso principal, luego detenga los procesos hijos después del tiempo de espera.
Script de Despliegue Automatizado
La descripción de Play The Event es administrada por un equipo de Más de 18 scripts Bash que automatizan cada aspecto del ciclo de vida de la aplicación en el VPS de OVHcloud.
Scripts de Despliegue
deploy-all.shdeploy-backend.shdeploy-frontend.shdeploy-analytics.shrestart-all.shstart-all.shstop-all.sh
Scripts de Setup y Mantenimiento
setup-nginx.shsetup-ssl.shsetup-mysql-databases.shsetup-analytics.shupdate-nginx-ssr.shupdate-vps-config.shcleanup-logs-vps.shwatch-logs.sh
El Despliegue Orquestado: deploy-all.sh
El script principal deploy-all.sh orquesta el despliegue de todos los servicios
con soporte para ejecución secuencial o paralela, omisión selectiva de servicios y
reporte detallado con tiempos de ejecución.
# Deploy completo (sequenziale)
./scripts/deploy-all.sh
# Deploy parallelo (più veloce)
./scripts/deploy-all.sh --parallel
# Solo frontend e analytics (salta backend)
./scripts/deploy-all.sh --skip-be
# Continua anche se un deploy fallisce
./scripts/deploy-all.sh --continue
El flujo de deploy-all.sh incluye:
- Parsing de argumentos: Soporte para
--parallel,--skip-be,--skip-fe,--skip-ai,--continue - Despliegue secuencial o paralelo: En modo paralelo, los tres servicios se lanzan como procesos en segundo plano, esperando la finalización de todos
- Health check: Después del despliegue, verifica que cada servicio responda correctamente a través de sus respectivos endpoints de health
- Reporte final: Muestra el estado de cada servicio (SUCCESS, ERROR, SKIPPED) con los tiempos de ejecución
El Despliegue del Backend
El script deploy-backend.sh gestiona todo el ciclo de vida del despliegue del backend
en 8 pasos automatizados:
# Step 1: Verifica prerequisiti (Java 21, Maven, MySQL)
# Step 2: Navigazione alla directory backend
# Step 3: Caricamento variabili da .env.prod + test connessione DB
# Step 4: Build Maven (mvnw clean package -DskipTests)
# Step 5: Verifica database e migrazioni Flyway
# Step 6: Creazione/aggiornamento servizio systemd
# Step 7: Restart servizio con verifica stato
# Step 8: Health check con retry (max 15 tentativi, 2s intervallo)
# Comandi utili post-deploy:
sudo systemctl status management-events-backend
sudo journalctl -u management-events-backend -f
curl http://localhost:8080/api/health
Gestión del VPS de OVHcloud
La plataforma funciona en un VPS OVHcloud con Ubuntu 24.04. los guiones start-all.sh,
stop-all.sh y restart-all.sh gestionan todo el ciclo de vida
de los servicios en el VPS.
# Ordine di avvio dei servizi:
# [1/5] Verifica e avvio MySQL
systemctl start mysql
mysql -u root -e "USE management_events_system;"
# [2/5] Stop servizi esistenti (pulizia)
systemctl stop management-events-backend
systemctl stop management-events-frontend
# [3/5] Avvio backend Spring Boot
systemctl start management-events-backend
# Attesa health check su localhost:8080/api/health
# [4/5] Avvio frontend Angular
systemctl start management-events-frontend
# Attesa health check su localhost:4200
# [5/5] Verifica e reload Nginx
systemctl reload nginx
# Verifica proxy funzionante
Orden de Arranque Crítico
El orden de arranque es fundamental: MySQL debe estar completamente operativo antes de que
el backend Spring Boot intente conectarse, de lo contrario Flyway fallará al ejecutar
las migraciones. Por este motivo, start-all.sh verifica no solo que MySQL esté
activo, sino también que la base de datos específica sea accesible, antes de proceder con el backend.
Migraciones de bases de datos con Flyway
El esquema de la base de datos MySQL de Play The Event está gestionado mediante 199 migraciones Flyway versionadas. Cada modificación al esquema es una migración SQL numerada que se ejecuta automáticamente al arrancar el backend Spring Boot.
backend/src/main/resources/db/migration/
├── V1__create_users_table.sql
├── V2__create_events_table.sql
├── V3__create_participants_table.sql
├── ...
├── V98__create_analytics_tables.sql
├── V99__create_tipologie_luogo_table.sql
├── V100__create_luoghi_table.sql
├── V101__create_festival_table.sql
├── V102__create_giornate_festival_table.sql
└── ... (199 migrazioni totali)
Flyway lleva el registro de las migraciones realizadas en la mesa flyway_schema_history.
Una vez que llegue allí, el backend compara las migraciones presentes en el classpath con las que ejecutó.
y aplicar sólo los nuevos. Esta información está garantizada:
- Evolución incremental: El esquema evoluciona gradualmente sin perder nunca datos
- Reproducibilidad: Cualquier instancia de la base de datos puede alcanzar el estado actual ejecutando todas las migraciones en orden
- Trazabilidad: Cada modificación al plan es un archivo SQL en el repositorio de Git, con autor, lugar y motivo de la modificación.
- Seguridad: Las migraciones son idempotentes y no pueden modificarse después de la ejecución (Flyway verifica el checksum)
Redis: Caché y Gestión de Sesiones
Redis utiliza un papel crítico en la arquitectura de Play The Event, gestionando tanto el espacio consultar frecuentemente como sesiones de usuario. La configuración está optimizada para usted. un entorno con memoria limitada.
# Avvio Redis con configurazione personalizzata
redis-server \
--appendonly yes \
--maxmemory 256mb \
--maxmemory-policy allkeys-lru
# appendonly yes → Persistenza AOF su disco
# maxmemory 256mb → Limite memoria massima
# maxmemory-policy → Eviction delle chiavi meno usate
Política todas las teclas-lru (Usado menos recientemente) fue elegido porque En un contexto de gestión de eventos, los datos más recientes son generalmente los más relevantes: Se priorizan los eventos activos, las sesiones actuales y las consultas más frecuentes. sobre el caché de datos antiguos o poco consultados.
Usos de Redis en la Plataforma
- Caché de consultas: Los resultados de las consultas más frecuentes (lista de eventos públicos, detalles del evento) se almacenan en caché para reducir la carga sobre MySQL
- Sesiones de usuario: Los datos de sesión se almacenan en Redis para soportar la escalabilidad horizontal del backend
- Rate limiting: Los contadores para el rate limiting de las APIs se gestionan en Redis con TTL automático
- Datos temporales: Tokens de verificación de email, códigos OTP y datos de checkout de Stripe con expiración automática
Gestión de Logs
El conjunto de scripts incluye herramientas dedicadas a la gestión de registros, esenciales para ellos. depurar en producción y mantener el espacio en disco del VPS.
Monitorización de Logs en Tiempo Real
El script watch-logs.sh ofrece un menú interactivo para el streaming de logs
en tiempo real, con 9 opciones que cubren todos los servicios:
Seleziona quale log visualizzare:
1) Backend (systemd journal)
2) Backend (application log)
3) Backend (error log)
4) Frontend (systemd journal)
5) Frontend (application log)
6) Frontend (error log)
7) Nginx (access log)
8) Nginx (error log)
9) Tutti i backend logs (multipli)
Utilice la opción 9 multitail (si está disponible) para mirar simultáneamente
registro systemd, registro de aplicaciones y registro de errores con prefijos de color. Sin cola múltiple,
un script de respaldo combina múltiples procesos tail -f con prefijos
[SYSTEMD], [APP] y [ERROR].
Limpieza Automática de Logs
El script cleanup-logs-vps.sh automatiza la limpieza de logs en la VPS,
escaneando los directorios de logs, eliminando los archivos y limpiando los journals systemd
más antiguos de 7 días.
# Directory monitorate per la pulizia
LOG_DIRS=(
"/var/log/management-events"
"/home/ubuntu/managementevents/logs"
"/opt/management-events/logs"
)
# Per ogni directory: conta file, calcola dimensione, elimina
# Pulisce anche journalctl logs > 7 giorni
sudo journalctl --vacuum-time=7d
# Mostra spazio disco rimanente
df -h /
Configuración SSL con Let's Encrypt
el guion setup-ssl.sh automatiza toda la configuración HTTPS para el dominio
playtheevent.com. El proceso incluye verificación de DNS, instalación de Certbot,
la generación de certificados y la configuración de renovación automática.
# Configurazione
DOMAIN="playtheevent.com"
WWW_DOMAIN="www.playtheevent.com"
# Step 1: Verifica DNS
# - Recupera IP della VPS (curl ifconfig.me)
# - Verifica che il dominio punti all'IP corretto (dig +short)
# - Controlla sia @ che www
# Step 2: Installazione Certbot
sudo apt install -y certbot python3-certbot-nginx
# Step 3: Generazione certificati
sudo certbot --nginx \
-d playtheevent.com \
-d www.playtheevent.com \
--email admin@playtheevent.com \
--agree-tos
# Step 4: Verifica rinnovo automatico (cron)
sudo certbot renew --dry-run
Monitorización y Health Check
El sistema de monitorización de Play The Event verifica la salud de todos los servicios después de cada despliegue y puede ejecutarse bajo demanda.
# Health check integrato nel deploy-all.sh:
# Backend - verifica risposta HTTP 200
curl -s -o /dev/null -w "%{http_code}" \
http://localhost:8080/api/health
# Frontend SSR - verifica risposta HTTP 200/301/302
curl -s -o /dev/null -w "%{http_code}" \
http://localhost:4200
# Analytics - verifica risposta HTTP 200
curl -s -o /dev/null -w "%{http_code}" \
http://localhost:8001/health
# Nginx - verifica proxy funzionante
curl -s https://playtheevent.com/health
El reporte final del despliegue muestra una vista clara del estado:
╔════════════════════════════════════════════╗
║ REPORT DEPLOY ║
╚════════════════════════════════════════════╝
Stato Servizi:
✓ Backend SUCCESS (2m 34s)
✓ Frontend SUCCESS (1m 12s)
✓ Analytics SUCCESS (45s)
Tempo totale: 4m 31s
URL di accesso:
• Frontend: https://playtheevent.com
• API: https://playtheevent.com/api
• Analytics: http://localhost:8001/docs
Resumen de infraestructura
Pila de infraestructura completa
- VPS: OVHcloud Ubuntu 24.04 LTS
- Containerización: Docker Compose para desarrollo (MySQL 8.4.3, Redis 7.4.1, phpMyAdmin, Redis Commander)
- Servidor web: Nginx como reverse proxy con SSL Let's Encrypt, rate limiting y compresión gzip
- Gestor de procesos: systemd para arranque automático y reinicio en caso de fallo de backend y frontend
- Base de datos: MySQL 8.4.3 con 199 migraciones versiones Flyway
- Cache: Redis 7.4.1 con 256 MB, política allkeys-lru, persistencia AOF
- Automatización: 18+ scripts Bash para despliegue, configuración, mantenimiento y monitorización
- SSL: Let's Encrypt con renovación automática usando Certbot
La infraestructura de Reproducir el evento La vista que incluye un proyecto gestionado por un único desarrollador puede contener un nivel Automatización y confiabilidad comparables a equipos más grandes, gracias a los scripts. Servicios bien construidos, impulsados por el sistema y una sólida configuración de Nginx.
El código fuente está disponible en GitHub.







