310 lines
9.6 KiB
PowerShell
310 lines
9.6 KiB
PowerShell
# ====================================================================
|
|
# AfterWork Server - Script de Déploiement Production
|
|
# ====================================================================
|
|
# Ce script automatise le processus de build et déploiement
|
|
# de l'API AfterWork sur le VPS via Kubernetes.
|
|
# Exécuter depuis la racine du projet ou depuis scripts/
|
|
# ====================================================================
|
|
|
|
param(
|
|
[ValidateSet("build", "push", "deploy", "all", "rollback", "status")]
|
|
[string]$Action = "all",
|
|
|
|
[string]$Version = "1.0.0",
|
|
|
|
[string]$Registry = "registry.lions.dev",
|
|
|
|
[switch]$SkipTests,
|
|
|
|
[switch]$Force
|
|
)
|
|
|
|
$ErrorActionPreference = "Stop"
|
|
|
|
# Racine du projet (parent du dossier scripts)
|
|
$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
|
|
$ProjectRoot = (Resolve-Path (Join-Path $ScriptDir "..")).Path
|
|
|
|
# Couleurs
|
|
function Write-Info { param($msg) Write-Host $msg -ForegroundColor Cyan }
|
|
function Write-Success { param($msg) Write-Host $msg -ForegroundColor Green }
|
|
function Write-Warning { param($msg) Write-Host $msg -ForegroundColor Yellow }
|
|
function Write-Error { param($msg) Write-Host $msg -ForegroundColor Red }
|
|
|
|
# Variables
|
|
$AppName = "afterwork-api"
|
|
$Namespace = "applications"
|
|
$ImageName = "$Registry/${AppName}:$Version"
|
|
$ImageLatest = "$Registry/${AppName}:latest"
|
|
|
|
Write-Info "======================================================================"
|
|
Write-Info " AfterWork Server - Déploiement Production"
|
|
Write-Info "======================================================================"
|
|
Write-Host ""
|
|
Write-Info "Configuration:"
|
|
Write-Host " - Action: $Action"
|
|
Write-Host " - Version: $Version"
|
|
Write-Host " - Registry: $Registry"
|
|
Write-Host " - Image: $ImageName"
|
|
Write-Host " - Namespace: $Namespace"
|
|
Write-Host " - Racine projet: $ProjectRoot"
|
|
Write-Host ""
|
|
|
|
# ======================================================================
|
|
# Build Maven
|
|
# ======================================================================
|
|
function Build-Application {
|
|
Write-Info "[1/5] Build Maven..."
|
|
|
|
Push-Location $ProjectRoot
|
|
try {
|
|
$mavenArgs = "clean", "package", "-Dquarkus.package.type=uber-jar"
|
|
if ($SkipTests) {
|
|
$mavenArgs += "-DskipTests"
|
|
} else {
|
|
$mavenArgs += "-DtestFailureIgnore=true"
|
|
}
|
|
|
|
& mvn $mavenArgs
|
|
if ($LASTEXITCODE -ne 0) {
|
|
Write-Error "Erreur lors du build Maven"
|
|
exit 1
|
|
}
|
|
|
|
$jar = Get-ChildItem -Path (Join-Path $ProjectRoot "target") -Filter "*-runner.jar" | Select-Object -First 1
|
|
if (-not $jar) {
|
|
Write-Error "JAR runner non trouvé dans target/"
|
|
exit 1
|
|
}
|
|
|
|
Write-Success "Build Maven réussi : $($jar.Name)"
|
|
} finally {
|
|
Pop-Location
|
|
}
|
|
}
|
|
|
|
# ======================================================================
|
|
# Build Docker Image
|
|
# ======================================================================
|
|
function Build-DockerImage {
|
|
Write-Info "[2/5] Build Docker Image..."
|
|
|
|
Push-Location $ProjectRoot
|
|
try {
|
|
$dockerDir = Join-Path $ProjectRoot "docker"
|
|
docker build -f (Join-Path $dockerDir "Dockerfile.prod") -t $ImageName -t $ImageLatest .
|
|
if ($LASTEXITCODE -ne 0) {
|
|
Write-Error "Erreur lors du build Docker"
|
|
exit 1
|
|
}
|
|
|
|
Write-Success "Image Docker créée : $ImageName"
|
|
} finally {
|
|
Pop-Location
|
|
}
|
|
}
|
|
|
|
# ======================================================================
|
|
# Push vers Registry
|
|
# ======================================================================
|
|
function Push-ToRegistry {
|
|
Write-Info "[3/5] Push vers Registry..."
|
|
|
|
$loginTest = docker login $Registry 2>&1
|
|
if ($LASTEXITCODE -ne 0 -and -not $loginTest.ToString().Contains("Succeeded")) {
|
|
Write-Warning "Connexion au registry nécessaire..."
|
|
docker login $Registry
|
|
if ($LASTEXITCODE -ne 0) {
|
|
Write-Error "Échec de connexion au registry"
|
|
exit 1
|
|
}
|
|
}
|
|
|
|
docker push $ImageName
|
|
if ($LASTEXITCODE -ne 0) {
|
|
Write-Error "Erreur lors du push de $ImageName"
|
|
exit 1
|
|
}
|
|
|
|
docker push $ImageLatest
|
|
if ($LASTEXITCODE -ne 0) {
|
|
Write-Error "Erreur lors du push de $ImageLatest"
|
|
exit 1
|
|
}
|
|
|
|
Write-Success "Images pushées vers $Registry"
|
|
}
|
|
|
|
# ======================================================================
|
|
# Déploiement Kubernetes
|
|
# ======================================================================
|
|
function Deploy-ToKubernetes {
|
|
Write-Info "[4/5] Déploiement Kubernetes..."
|
|
|
|
$kubectlCheck = kubectl version --client 2>&1
|
|
if ($LASTEXITCODE -ne 0) {
|
|
Write-Error "kubectl n'est pas installé ou configuré"
|
|
exit 1
|
|
}
|
|
|
|
$k8sDir = Join-Path $ProjectRoot "kubernetes"
|
|
Write-Info "Création du namespace $Namespace..."
|
|
kubectl create namespace $Namespace --dry-run=client -o yaml | kubectl apply -f -
|
|
|
|
Write-Info "Application des ConfigMaps et Secrets..."
|
|
kubectl apply -f (Join-Path $k8sDir "afterwork-configmap.yaml")
|
|
if ($LASTEXITCODE -ne 0) {
|
|
Write-Warning "ConfigMap déjà existante ou erreur"
|
|
}
|
|
|
|
if (-not $Force) {
|
|
Write-Warning "⚠️ ATTENTION : Vérifiez que les secrets sont correctement configurés !"
|
|
Write-Warning " Fichier : kubernetes/afterwork-secrets.yaml"
|
|
$confirm = Read-Host "Continuer le déploiement? (o/N)"
|
|
if ($confirm -ne "o" -and $confirm -ne "O") {
|
|
Write-Warning "Déploiement annulé"
|
|
exit 0
|
|
}
|
|
}
|
|
|
|
kubectl apply -f (Join-Path $k8sDir "afterwork-secrets.yaml")
|
|
if ($LASTEXITCODE -ne 0) {
|
|
Write-Error "Erreur lors de l'application des secrets"
|
|
exit 1
|
|
}
|
|
|
|
Write-Info "Déploiement de l'application..."
|
|
kubectl apply -f (Join-Path $k8sDir "afterwork-deployment.yaml")
|
|
if ($LASTEXITCODE -ne 0) {
|
|
Write-Error "Erreur lors du déploiement"
|
|
exit 1
|
|
}
|
|
|
|
kubectl apply -f (Join-Path $k8sDir "afterwork-service.yaml")
|
|
if ($LASTEXITCODE -ne 0) {
|
|
Write-Error "Erreur lors de la création du service"
|
|
exit 1
|
|
}
|
|
|
|
kubectl apply -f (Join-Path $k8sDir "afterwork-ingress.yaml")
|
|
if ($LASTEXITCODE -ne 0) {
|
|
Write-Error "Erreur lors de la création de l'ingress"
|
|
exit 1
|
|
}
|
|
|
|
Write-Success "Déploiement Kubernetes réussi"
|
|
|
|
Write-Info "Attente du rollout..."
|
|
kubectl rollout status deployment/$AppName -n $Namespace --timeout=5m
|
|
if ($LASTEXITCODE -ne 0) {
|
|
Write-Warning "Timeout ou erreur lors du rollout"
|
|
}
|
|
}
|
|
|
|
# ======================================================================
|
|
# Vérification du déploiement
|
|
# ======================================================================
|
|
function Verify-Deployment {
|
|
Write-Info "[5/5] Vérification du déploiement..."
|
|
|
|
Write-Info "Pods:"
|
|
kubectl get pods -n $Namespace -l app=$AppName
|
|
|
|
Write-Info "`nService:"
|
|
kubectl get svc -n $Namespace $AppName
|
|
|
|
Write-Info "`nIngress:"
|
|
kubectl get ingress -n $Namespace $AppName
|
|
|
|
Write-Info "`nTest Health Check..."
|
|
Start-Sleep -Seconds 5
|
|
|
|
try {
|
|
$response = Invoke-WebRequest -Uri "https://api.lions.dev/afterwork/q/health/ready" -UseBasicParsing -TimeoutSec 10
|
|
if ($response.StatusCode -eq 200) {
|
|
Write-Success "✓ API accessible : https://api.lions.dev/afterwork"
|
|
Write-Success "✓ Health check : OK"
|
|
} else {
|
|
Write-Warning "⚠ Health check retourné : $($response.StatusCode)"
|
|
}
|
|
} catch {
|
|
Write-Warning "⚠ Impossible de joindre l'API (normal si DNS pas encore propagé)"
|
|
Write-Info " Vérifiez manuellement : https://api.lions.dev/afterwork/q/health"
|
|
}
|
|
|
|
Write-Success "`nDéploiement terminé avec succès !"
|
|
}
|
|
|
|
# ======================================================================
|
|
# Rollback
|
|
# ======================================================================
|
|
function Rollback-Deployment {
|
|
Write-Warning "Rollback du déploiement..."
|
|
|
|
kubectl rollout undo deployment/$AppName -n $Namespace
|
|
if ($LASTEXITCODE -ne 0) {
|
|
Write-Error "Erreur lors du rollback"
|
|
exit 1
|
|
}
|
|
|
|
kubectl rollout status deployment/$AppName -n $Namespace
|
|
Write-Success "Rollback réussi"
|
|
}
|
|
|
|
# ======================================================================
|
|
# Status
|
|
# ======================================================================
|
|
function Get-Status {
|
|
Write-Info "Status de $AppName..."
|
|
|
|
Write-Info "`nPods:"
|
|
kubectl get pods -n $Namespace -l app=$AppName
|
|
|
|
Write-Info "`nDéploiement:"
|
|
kubectl get deployment -n $Namespace $AppName
|
|
|
|
Write-Info "`nService:"
|
|
kubectl get svc -n $Namespace $AppName
|
|
|
|
Write-Info "`nIngress:"
|
|
kubectl get ingress -n $Namespace $AppName
|
|
|
|
Write-Info "`nLogs récents (20 dernières lignes):"
|
|
kubectl logs -n $Namespace -l app=$AppName --tail=20
|
|
}
|
|
|
|
# ======================================================================
|
|
# Exécution selon l'action
|
|
# ======================================================================
|
|
|
|
switch ($Action) {
|
|
"build" {
|
|
Build-Application
|
|
Build-DockerImage
|
|
}
|
|
"push" {
|
|
Push-ToRegistry
|
|
}
|
|
"deploy" {
|
|
Deploy-ToKubernetes
|
|
Verify-Deployment
|
|
}
|
|
"all" {
|
|
Build-Application
|
|
Build-DockerImage
|
|
Push-ToRegistry
|
|
Deploy-ToKubernetes
|
|
Verify-Deployment
|
|
}
|
|
"rollback" {
|
|
Rollback-Deployment
|
|
}
|
|
"status" {
|
|
Get-Status
|
|
}
|
|
}
|
|
|
|
Write-Info "`n======================================================================"
|
|
Write-Info "Terminé!"
|
|
Write-Info "======================================================================"
|