L'Infrastructure Derrière la Plateforme
Construire une plateforme comme Play The Event ne signifie pas seulement écrire du code applicatif : cela signifie aussi concevoir une infrastructure qui garantisse fiabilité, reproductibilité et facilité de déploiement. De l'environnement de développement local au VPS de production, chaque composant d'infrastructure a été pensé pour réduire les temps de déploiement, minimiser les erreurs manuelles et garantir que les services soient toujours disponibles.
Cet article explore l'ensemble du stack DevOps de Play The Event : de la conteneurisation avec Docker Compose à la configuration Nginx avec SSL, des services systemd aux scripts d'automatisation, en passant par la gestion des migrations de base de données et du cache Redis.
Ce que Vous Trouverez dans Cet Article
- Docker Compose pour l'environnement de développement avec MySQL, Redis, phpMyAdmin et Redis Commander
- Nginx comme reverse proxy avec SSL Let's Encrypt, rate limiting et security headers
- Services systemd pour démarrage automatique du backend et du frontend
- 18+ scripts Bash pour déploiement, démarrage, arrêt, redémarrage et maintenance
- 199 migrations Flyway pour l'évolution du schéma MySQL
- Redis avec configuration 256MB et politique allkeys-lru
- Gestion des logs et surveillance de la santé des services
Docker Compose : L'Environnement de Développement
L'environnement de développement de Play The Event est entièrement conteneurisé via Docker Compose. Quatre services orchestrés garantissent que chaque développeur puisse démarrer l'ensemble du stack avec une seule commande, sans se soucier d'installer et de configurer manuellement MySQL, Redis ou les outils d'administration.
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
Ces aspects spécifiques de la configuration Docker :
- Health checks : MySQL et Redis disposent de health checks intégrés. Les services dépendants (phpMyAdmin, Redis Commander) attendent que les services de base soient prêts avant de démarrer
- Volumes persistants :
mysql_dataetredis_datagarantissent que les données survivent au redémarrage des conteneurs - MySQL optimisé :
utf8mb4pour le support Unicode complet,innodb_buffer_pool_size=1Gpour des performances optimales, jusqu'à 200 connexions simultanées - Redis avec AOF :
appendonly yesactive la persistance à l'écran. La politiqueallkeys-lruÉvitez d'utiliser la mémoire des anciens Premiers ministres le mois dernier d'utilisation
Ports des Services de Développement
- 3306 - MySQL 8.4.3 (base de données principale)
- 6379 - Redis 7.4.1 (cache et sessions)
- 8080 - Backend Spring Boot (API REST)
- 4200 - Frontend Angular (serveur de développement)
- 8081 - phpMyAdmin (gestion de base de données)
- 8082 - Redis Commander (gestion du cache)
Nginx : Reverse Proxy avec SSL
En production, Nginx fait office de proxy inverse devant tous les services de Jouez à l'événement. Les informations sur la terminaison SSL, le routage des requêtes, la compression gzip, la mise en cache d’actifs statiques et protection par limitation de taux.
# 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";
}
}
Sécurité au Niveau Réseau
La configuration Nginx implémente davantage de stratégies de protection :
- Rate limiting à deux niveaux : Les APIs générales sont limitées à 100 requêtes par minute par IP, tandis que les endpoints d'authentification ont une limite beaucoup plus restrictive de 10 requêtes par minute, avec réponse HTTP 429 en cas de dépassement
- SSL avec Let's Encrypt : Certificats gratuits avec renouvellement automatique via Certbot. Les scripts
setup-ssl.shautomatisez la vérification DNS, l'installation de Certbot et la génération de certificats - En-têtes de sécurité : Protection contre le détournement de clic (
X-Frame-Options), reniflant MIME (X-Content-Type-Options) et le XSS (X-XSS-Protection) - Blocage des fichiers sensibles : Toute requête vers des fichiers commençant par
.(comme.env,.git) est automatiquement bloquée
Endpoint de Health Check
Nginx expose un point de terminaison /health dédié à la surveillance externe. Point de terminaison Cet
J'aimerais une réponse simple sans toucher au backend, permettant les systèmes de surveillance
vérifiez que le proxy inverse est actif.
# 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 : Services à Démarrage Automatique
Le backend Spring Boot et le frontend Angular sont similaires aux services systemd sur le VPS Ubuntu 24.04. Il existe une garantie que les services s'arrêteront automatiquement après un crash ou un rachat du serveur.
[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
Aspects importants de la configuration de systemd :
- Dépendances : Les backends déclarent
After=mysql.serviceetWants=mysql.service, garantissant que MySQL est toujours en cours d'exécution avant l'application Spring Boot - Redémarrage automatique :
Restart=on-failureavecRestartSec=10sredémarre automatiquement le service après un crash, avec une limite de 3 tentatives en 5 minutes pour éviter les boucles infinies - Variables d'environnement : Les configurations sensibles sont chargées depuis
.env.prodviaEnvironmentFile, gardant les identifiants hors du code source - Sécurité :
NoNewPrivileges=trueempêche l'escalade des privilèges,PrivateTmp=trueisole le répertoire temporaire du service - Arrêt gracieux :
KillSignal=SIGTERMavecKillMode=mixedenvoie d'abord un signal de terminaison au processus principal, puis force l'arrêt des processus enfants après le timeout
Script de Déploiement Automatisé
Le déploiement de Play The Event est géré par une suite de Plus 18 scripts Bash Vous pouvez visualiser automatiquement le cycle de candidature sur le VPS OVHcloud.
Scripts de Déploiement
deploy-all.shdeploy-backend.shdeploy-frontend.shdeploy-analytics.shrestart-all.shstart-all.shstop-all.sh
Scripts de Setup et Maintenance
setup-nginx.shsetup-ssl.shsetup-mysql-databases.shsetup-analytics.shupdate-nginx-ssr.shupdate-vps-config.shcleanup-logs-vps.shwatch-logs.sh
Le Déploiement Orchestré : déploiement-all.sh
Les principaux scripts deploy-all.sh les orchestres déploient tous les services
avec prise en charge de l'exécution séquentielle ou parallèle, sélection de services et
rapport détaillé avec les délais d'exécution.
# 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
Les flux déployer-all.sh incluent :
- Parsing des arguments : Support pour
--parallel,--skip-be,--skip-fe,--skip-ai,--continue - Déploiement séquentiel ou parallèle : En mode parallèle, les trois services sont lancés comme processus en arrière-plan, avec attente de la complétion de tous
- Health check : Après le déploiement, vérifie que chaque service répond correctement via ses endpoints de health respectifs
- Rapport final : Affiche l'état de chaque service (SUCCESS, ERROR, SKIPPED) avec les temps d'exécution
Le Déploiement du Backend
Les scripts deploy-backend.sh gérer l'intégralité du cycle de vie du déploiement backend
en 8 étapes automatiques :
# 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
Gestion du VPS OVHcloud
La plateforme tourne sur un VPS OVHcloud avec Ubuntu 24.04. Les scripts start-all.sh,
stop-all.sh et restart-all.sh gèrent l'intégralité du cycle de vie
des services sur le 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
Ordre de Démarrage Critique
L'ordre de démarrage est fondamental : MySQL doit être complètement opérationnel avant que
le backend Spring Boot tente de se connecter, sinon Flyway échouera lors de l'exécution
des migrations. C'est pourquoi start-all.sh vérifie non seulement que MySQL est
actif, mais aussi que la base de données spécifique est accessible, avant de procéder avec le backend.
Migrations de Base de Données avec Flyway
Le schéma de base de l'interface utilisateur MySQL Jouez à l'événement est géré 199 migrations versionnées. Chaque modification du schéma L'invite d'un certain nom de migrations SQL ici est automatiquement exécutée à la place du backend SpringBoot.
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 conserve les enregistrements des migrations déjà exécutées sur la table flyway_schema_history.
After download, the backend compares the migrations present in the classpath with previously executed cells
et n'applique que les nouvelles. Ces approches garanties :
- Evolution incrémentielle : Le modèle évolue progressivement sans perdre les femmes
- Reproductibilité : N'importe quelle instance de la base de données peut atteindre l'état actuel en exécutant toutes les migrations dans l'ordre
- Traçabilité : Cette modification du schéma est un fichier SQL dans le répertoire Git, avec l'auteur, la date et le motif de la modification
- Sécurité : Les migrations sont idempotentes et ne peuvent pas être modifiées après exécution (Flyway vérifie le checksum)
Redis : Cache et Gestion des Sessions
Redis joue un rôle essentiel dans l'architecture de Play The Event, en gérant le cache de demandes fréquentes et de séances utiles. La configuration est optimisée pour vous un environnement avec une mémoire limitée.
# 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
La politique allkeys-lru (La moins récemment utilisée) une voiture qui a été choisie Dans le cas présent, les femmes les plus récentes sont généralement les plus pertinentes : les événements les plus fréquents, les sessions en cours et les demandes les plus fréquentes sur la priorité sur les caches de femmes plus âgées ou plus fréquemment consultées.
Utilisations de Redis sur la Plateforme
- Cache de requêtes : Les résultats des requêtes les plus fréquentes (liste des événements publics, détails d'un événement) sont mis en cache pour réduire la charge sur MySQL
- Sessions utilisateur : Les données de session sont stockées dans Redis pour supporter la scalabilité horizontale du backend
- Rate limiting : Les compteurs pour le rate limiting des APIs sont gérés dans Redis avec TTL automatique
- Données temporaires : Tokens de vérification d'email, codes OTP et données de checkout Stripe avec expiration automatique
Gestion des Logs
La suite de scripts comprend des outils utiles pour la gestion des logs, indispensables pour panne de production et de maintenance de l’espace disque sur le VPS.
Surveillance des Logs en Temps Réel
Les scripts watch-logs.sh propose un menu interactif pour diffuser les journaux
en bobine temporelle, avec 9 options disponibles pour tous les services :
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)
Utiliser l'option 9 multitail (disponible) pour visualiser simultanément
les journaux système, les journaux d'application et les journaux d'erreurs avec préfixes de couleur. En l'absence de multiqueue,
un script de réplique combine plusieurs processus tail -f avec les préfixes
[SYSTEMD], [APP] et [ERROR].
Nettoyage Automatique des Logs
Les scripts cleanup-logs-vps.sh automatiser le nettoyage des logs sur le VPS,
scanner les répertoires de journaux, supprimer les fichiers et effacer les journaux systemd
plus de 7 jours.
# 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 /
Configuration SSL avec Let's Encrypt
Les scripts setup-ssl.sh automatiser l'intégrité de la configuration HTTPS pour le domaine
playtheevent.com. Le processus comprend la vérification DNS, l'installation de Certbot,
la génération de certificats et la configuration du renouvellement automatique.
# 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
Surveillance et Health Check
Le système de surveillance de Play The Event vérifie la santé de tous les services un moment que vous avez déployé et qui peut être exécuté à la demande.
# 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
Le rapport final sur le déploiement est le suivant :
╔════════════════════════════════════════════╗
║ 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
Récapitulatif de l'Infrastructure
Stack Infrastructurel Complet
- VPS : OVHcloud Ubuntu 24.04 LTS
- Conteneurisation : Docker Compose pour le développement (MySQL 8.4.3, Redis 7.4.1, phpMyAdmin, Redis Commander)
- Serveur web : Nginx comme reverse proxy avec SSL Let's Encrypt, rate limiting et compression gzip
- Gestionnaire de processus : systemd pour démarrage automatique et redémarrage en cas d'échec du backend et du frontend
- Base de données : MySQL 8.4.3 avec 199 migrations Flyway versionnées
- Cache : Redis 7.4.1 avec 256MB, politique allkeys-lru, persistance AOF
- Automatisation : 18+ scripts Bash pour déploiement, configuration, maintenance et surveillance
- SSL : Let's Encrypt avec renouvellement automatique via Certbot
L'infrastructure de Play The Event démontre comment même un projet géré par un seul développeur peut atteindre un niveau d'automatisation et de fiabilité comparable à des équipes plus grandes, grâce à des scripts bien structurés, des services systemd et une configuration Nginx solide.
La source du code est disponible maintenant GitHub.







