Cours NestJS · Module 9: Déploiement et infrastructure
PROJET : Déploiement complet d'une application NestJS en production
Dans cette leçon2
Légat ! Ton application tourne sur ton ordinateur portable, mais le consul Caesar.js pose les questions qui surgissent à chaque vrai déploiement : que se passe-t-il quand le serveur s'éteint à trois heures du matin ? Qui remarquera que la base ralentit ? Comment sais-tu que la sauvegarde d'hier peut être restaurée ? Le consul te confie le plus grand défi : le déploiement complet de la légion romaine en production. C'est le véritable test des compétences que tu as acquises pendant notre campagne NestJS.
Spécification du projet
Ta mission consiste à créer un système de déploiement complet pour l'application Legionary Legion API. Chaque partie s'appuie sur les leçons de ce module et des précédents, alors avant de commencer, reviens-y comme à des cartes d'état-major. Les heures indiquées sont une durée de travail approximative.
1. Infrastructure (4-5 heures)
- Configuration Docker et Docker Compose
- Mise en place des charts Kubernetes/Helm
- Configuration du pipeline CI/CD
- Surveillance et journalisation
Commence par une image construite en multi-stage build et un fichier Compose qui lance l'application avec MongoDB et Redis. Dans Kubernetes, décris les réplicas, la stratégie de rolling update et les sondes readiness et liveness. Le pipeline doit lancer les tests, construire l'image et ne la déployer qu'une fois les tests au vert.
2. Sécurité (2-3 heures)
- Implémentation SSL/TLS
- En-têtes de sécurité et rate limiting
- Gestion des secrets
- Analyse des vulnérabilités
Tu connais déjà HTTPS, les en-têtes de Helmet et les limites du throttler. Garde les secrets hors du dépôt et de l'image, et fais en sorte que l'application refuse de démarrer quand l'un d'eux manque. Ajoute au pipeline un scanner de vulnérabilités, par ex. Trivy, pour qu'une image présentant une faille critique n'arrive jamais en production.
3. Performances (2-3 heures)
- Load balancing et auto-scaling
- Stratégie de cache
- Optimisation de la base de données
- Mise en place d'un CDN
Mesure avant d'optimiser : le résultat d'un test de charge avant et après tes changements est la meilleure preuve. Adapte les index aux requêtes les plus fréquentes, ajoute un cache Redis avec une invalidation bien pensée, et des en-têtes de cache pour le CDN. L'autoscaling ajoute des réplicas selon des métriques comme le CPU, donc l'application doit être sans état : les sessions et le cache vivent dans Redis, pas dans la mémoire du processus.
4. Surveillance (2-3 heures)
- Health checks
- Collecte de métriques
- Système d'alertes
- Agrégation des logs
Sépare les endpoints de santé en liveness et readiness, expose les métriques pour Prometheus, et écris les logs en JSON avec un identifiant de requête. Une alerte ne doit réveiller quelqu'un que lorsqu'il faut agir : une alarme trop bruyante cesse vite d'être entendue.
5. Sauvegarde et récupération (1-2 heures)
- Sauvegardes automatiques
- Plan de reprise après sinistre
- Vérifications de l'intégrité des données
Lance les sauvegardes automatiquement, fixe ton RTO et ton RPO, puis effectue une restauration complète sur un environnement neuf et note combien de temps elle a pris.
Critères d'évaluation
- Complétude - tous les composants fonctionnent ensemble
- Sécurité - des protections adaptées à chaque couche, du TLS aux secrets
- Performances - l'application supporte le trafic de production, ce que confirme un test de charge
- Surveillance - une observabilité complète : métriques, logs et alertes
- Documentation - des runbooks de déploiement et de restauration
Le mentor évaluera le projet à partir du dépôt, donc le README doit contenir les commandes de lancement, une description de l'architecture et les résultats du test de restauration. Je te recommande d'écrire le runbook en même temps que la configuration, et non à la fin : ce que tu ne notes pas tout de suite ne sera plus qu'une supposition à trois heures du matin.
Bonne chance, légat ! Ta légion compte sur toi, et tu enverras le système terminé à ton mentor à la fin du module.
Code de cette leçon : deployment-project/docker-compose.yml
1# PROJET : déploiement complet en production d'une application NestJS
2
3version: '3.8'
4
5services:
6 # === API NestJS ===
7 api:
8 build:
9 context: .
10 dockerfile: Dockerfile
11 container_name: roman-api
12 restart: unless-stopped
13 ports:
14 - "4000:4000"
15 environment:
16 NODE_ENV: production
17 PORT: 4000
18 MONGO_URI: mongodb://mongo:27017/roman_empire
19 REDIS_HOST: redis
20 REDIS_PORT: 6379
21 JWT_SECRET: ${JWT_SECRET}
22 ALLOWED_ORIGINS: https://roman-empire.com
23 depends_on:
24 mongo:
25 condition: service_healthy
26 redis:
27 condition: service_healthy
28 healthcheck:
29 test: ["CMD", "node", "-e",
30 "require('http').get('http://localhost:4000/health', (r) => { process.exit(r.statusCode === 200 ? 0 : 1) })"]
31 interval: 30s
32 timeout: 10s
33 retries: 3
34 start_period: 40s
35 networks:
36 - roman-network
37
38 # === MongoDB ===
39 mongo:
40 image: mongo:7
41 container_name: roman-mongodb
42 restart: unless-stopped
43 volumes:
44 - mongo-data:/data/db
45 - ./scripts/backup.sh:/scripts/backup.sh
46 environment:
47 MONGO_INITDB_DATABASE: roman_empire
48 healthcheck:
49 test: ["CMD", "mongosh", "--eval", "db.runCommand('ping').ok"]
50 interval: 10s
51 timeout: 5s
52 retries: 5
53 networks:
54 - roman-network
55
56 # === Redis Cache ===
57 redis:
58 image: redis:7-alpine
59 container_name: roman-redis
60 restart: unless-stopped
61 command: redis-server --appendonly yes
62 volumes:
63 - redis-data:/data
64 healthcheck:
65 test: ["CMD", "redis-cli", "ping"]
66 interval: 10s
67 timeout: 3s
68 retries: 3
69 networks:
70 - roman-network
71
72 # === Nginx Reverse Proxy ===
73 nginx:
74 image: nginx:alpine
75 container_name: roman-nginx
76 restart: unless-stopped
77 ports:
78 - "80:80"
79 volumes:
80 - ./nginx.conf:/etc/nginx/nginx.conf:ro
81 depends_on:
82 - api
83 networks:
84 - roman-network
85
86# Volumes
87volumes:
88 mongo-data:
89 driver: local
90 redis-data:
91 driver: local
92
93# Network
94networks:
95 roman-network:
96 driver: bridge
97
98# Commandes :
99# docker-compose up -d # Run
100# docker-compose logs -f api # Logs API
101# docker-compose down # Stop
102# docker-compose ps # Status
103Tu as repéré une erreur dans cette leçon ?