pipeline { triggers { pollSCM('* * * * *') } agent { docker { image 'node:20' // 🧠 Lance toutes les étapes dans un conteneur Node 20 args '-u root:root -v /var/run/docker.sock:/var/run/docker.sock' // permet d'utiliser docker dans le conteneur } } environment { REGISTRY_URL = 'registry.wk-archi-o24a-15m-g3.fr' IMAGE_NAME = 'the-tip-top-frontend' DEPLOY_PATH = '/srv/devops/the-tip-top' DEPLOY_HOST = 'https://dsp5-archi-o24a-15m-g3.fr' } stages { stage('Checkout') { steps { echo "📦 Récupération du code source depuis Gitea..." checkout scm } } stage('Install dependencies') { steps { echo "📦 Installation des dépendances NPM..." sh 'npm ci' } } stage('Build Next.js') { steps { echo "⚙️ Compilation de l’application Next.js (production)..." sh 'npm run build' } } stage('Build Docker image') { steps { echo "🐳 Construction de l’image Docker frontend..." sh """ docker build -t ${REGISTRY_URL}/${IMAGE_NAME}:${BUILD_NUMBER} . docker tag ${REGISTRY_URL}/${IMAGE_NAME}:${BUILD_NUMBER} ${REGISTRY_URL}/${IMAGE_NAME}:latest """ } } stage('Push to Registry') { steps { echo "📤 Envoi de l’image vers le registre privé..." withCredentials([usernamePassword(credentialsId: 'registry-credentials', usernameVariable: 'USER', passwordVariable: 'PASS')]) { sh """ echo "$PASS" | docker login ${REGISTRY_URL} -u "$USER" --password-stdin docker push ${REGISTRY_URL}/${IMAGE_NAME}:${BUILD_NUMBER} docker push ${REGISTRY_URL}/${IMAGE_NAME}:latest """ } } } stage('Deploy') { steps { echo "🚀 Déploiement du frontend via Docker Compose..." sh """ cd ${DEPLOY_PATH} docker compose pull frontend docker compose up -d --no-deps --force-recreate frontend """ } } stage('Health Check') { steps { echo "🩺 Vérification de la disponibilité du frontend..." script { def success = false for (int i = 1; i <= 3; i++) { echo "⏳ Tentative #${i} (attente ${i * 10}s)..." sh "sleep ${i * 10}" def code = sh(script: "curl -k -s -o /dev/null -w '%{http_code}' ${DEPLOY_HOST} || echo 000", returnStdout: true).trim() echo "➡️ Réponse HTTP : ${code}" if (code == '200' || code == '301' || code == '302') { success = true break } } if (!success) { error("❌ Le frontend ne répond pas après plusieurs tentatives.") } } } } } post { success { echo "✅ Déploiement réussi du frontend !" } failure { echo "❌ Échec du pipeline frontend." } } }