TP10 : CI/CD, Observabilité et Multi-environnement
Objectif du TP
Construire un workflow complet pour une application Node.js : - CI/CD : Automatiser les tests et le build via Docker. - Multi-environnement : Gérer des configurations distinctes pour le développement et la production. - Observabilité : Rendre l'application capable d'exposer son état interne (logs et métriques).
Rendu attendu
- Le fichier
docker-compose.yamlgérant les multi-environnements. - Le fichier
Dockerfile(ou plusieurs si nécessaire pour le CI). - Vos notes de carnet avec les réponses aux questions.
1. Pour débuter : L'application enrichie
Nous reprenons notre application Node.js du TP9, mais nous lui ajoutons quelques fonctionnalités pour suivre son usage.
app.js
const express = require('express');
const app = express();
const port = process.env.PORT || 3000;
const env = process.env.APP_ENV || "dev";
let counter = 0;
let errors = 0;
// Middleware de logging simple
app.use((req, res, next) => {
console.log(`[${new Date().toISOString()}] ${req.method} ${req.url} - Env: ${env}`);
next();
});
app.get('/', (req, res) => {
counter++;
res.json({
message: "Bienvenue sur l'API",
env: env,
counter: counter
});
});
app.get('/error', (req, res) => {
errors++;
res.status(500).json({ error: "Une erreur simulée s'est produite" });
});
// Endpoint de métriques pour l'observabilité
app.get('/metrics', (req, res) => {
res.json({
requests_total: counter + errors,
errors_total: errors,
uptime: process.uptime()
});
});
app.listen(port, () => {
console.log(`🚀 Serveur démarré sur le port ${port} en mode ${env}`);
});
2. CI/CD avec Docker
L'idée de la CI (Intégration Continue) est de valider chaque changement avant qu'il ne soit déployé. Si un test échoue, le pipeline doit s'arrêter immédiatement.
- Ajouter des tests : Faites générer un test très simple par une IA dans un dossier
tests(ex: vérifier qu'une route répond 200) en utilisant un outil commejest. - Linting : Configurez un linter genre
eslintpour vérifier la qualité du code. - Service de test dans Docker :
Créez un service
testdans votredocker-compose.yaml. Ce service ne doit pas lancer l'app, mais uniquement les tests.
Le mécanisme d'échec : Docker (et les outils de CI) se basent sur l'exit code du processus. -
exit 0: Tout va bien, le pipeline continue. -exit 1(ou autre) : Erreur détectée, le pipeline s'arrête.Exercice à compléter :
# Dans votre docker-compose.yaml services: test: build: . command: npm test # <-- Si cette commande échoue, l'exit code sera... ?Question : Pourquoi est-il préférable de lancer les tests dans Docker plutôt que sur votre machine directement lors d'un pipeline CI ?
3. Gestion Multi-environnement (App vs Infra)
Plutôt que d'avoir des fichiers indépendants, Docker permet de "surcharger" (override) une configuration. On sépare donc : - L'Application : Décrite dans le fichier de base. - L'Infrastructure : Décrite dans le fichier de production (overrides).
Fichier de base : docker-compose.yaml
Ce fichier contient la structure commune à tous vos environnements.
Fichier de production : docker-compose.prod.yaml
Ce fichier vient modifier ou ajouter des éléments à la base. Complétez les trous ci-dessous pour mapper l'application sur le port 80 et ajouter une politique de redémarrage automatique.
services:
app:
# À COMPLÉTER : Mapper le port 80 de l'hôte sur le 3000 du conteneur
ports:
- "___:3000"
# À COMPLÉTER : Ajouter la politique pour redémarrer automatiquement en cas de crash
restart: _________
environment:
- APP_ENV=production
Lancement en fusionnant les fichiers
Pour tester votre configuration de production :
Quel est l'avantage de cette méthode "d'override" plutôt que d'avoir deux fichiers Compose totalement indépendants si vous décidez de rajouter un nouveau réseau ou un nouveau volume demain ?
4. Observabilité & Prometheus
L'observabilité consiste à pouvoir comprendre l'état interne de votre système (logs et métriques) uniquement à partir des données qu'il expose.
Les Logs : Le fil d'Ariane
Les logs sont des événements textuels (ex: "Échec de connexion de l'utilisateur X"). - Pourquoi les structurer ? Si vos logs sont en JSON, une machine pourra les lire et créer des alertes automatiquement ("Alerte : 50 erreurs en 2 min !").
Les Métriques : Le tableau de bord
À l'inverse des logs, les métriques sont des chiffres montrant l'état actuel (ex: "42 utilisateurs connectés").
- Simulation d'usage : Lancez un petit script ou utilisez
curlen boucle pour appeler la racine/et faire monter vos compteurs. Provoquez manuellement des erreurs via/error. - Vérification : Consultez
/metricspour voir l'évolution.
Intégration Prometheus (Obligatoire via Override)
Nous allons maintenant ajouter Prometheus pour qu'il vienne récupérer vos métriques automatiquement. Mais attention : Prometheus ne doit être présent qu'en production !
Exercice à compléter : Ajoutez le service prometheus uniquement dans votre fichier docker-compose.prod.yaml.
# Dans docker-compose.prod.yaml
services:
prometheus:
image: prom/prometheus
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
ports:
- "9090:9090"
app:
# ... vos configurations précédentes
N'oubliez pas de créer le fichier
prometheus.ymlpour dire à Prometheus de venir "scraper" l'application Express sur le port 3000.Pourquoi est-il plus propre d'ajouter Prometheus dans le fichier
prod.yamlplutôt que dans le fichier de basedocker-compose.yaml? Posez-vous la question du besoin de monitoring en phase de développement pur.
5. Conclusion
À la fin de ce TP, vous devez avoir un environnement capable de : - Rejeter un build si les tests ne passent pas. - Basculer facilement entre une configuration de test locale et une mise en ligne. - Surveiller la santé de votre application en temps réel sans avoir à fouiller manuellement les fichiers de logs.