33800 Docs

← Retour

Proposition : Vrai Blue-Green Deployment dans smart-deploy

Date : 10/02/2026 Status : A VALIDER Scope : smart-deploy (strategies/docker.sh, lib/nginx.sh), nginx VM

Probleme actuel

La strategie zero-downtime dans docker.sh n'est pas du vrai zero-downtime :

1. Start staging (port+10000)
2. Health check staging          ← OK jusque la
3. STOP staging                  ← les 2 sont down
4. STOP production               ← les 2 sont down
5. Start nouveau sur port prod   ← downtime ~3-5s

Il y a un trou entre l'etape 3 et 5 ou RIEN ne repond. C'est un "validated restart", pas du blue-green.

Solution : Blue-Green via Nginx upstream swap

Principe

AVANT                                  APRES
┌─────────┐    ┌──────────┐           ┌─────────┐    ┌──────────┐
│  nginx   │───►│  BLUE    │           │  nginx   │───►│  GREEN   │
│          │    │ port 5501│           │          │    │ port 5511│
└─────────┘    └──────────┘           └─────────┘    └──────────┘
                                                      ┌──────────┐
                                                      │  BLUE    │ ← drain + stop
                                                      │ port 5501│
                                                      └──────────┘

Nginx fait le switch atomiquement. L'ancien container continue de servir les requetes en cours pendant le switch. Zero requete perdue.

Flow detaille

1. Identifier le slot actif (BLUE=port, GREEN=port+10)
   - Lire /etc/nginx/sites-available/<domain>.conf
   - Trouver le port actif dans proxy_pass
   - L'autre slot = le nouveau

2. Build & Push image (inchange)

3. Start GREEN container (port inactif)
   - docker compose up -d avec le port GREEN
   - Container name: <name>-green ou <name>-blue selon le slot

4. Health check GREEN (nos nouvelles etapes 9a/9b/9c)
   - 9a: Container running
   - 9b: Port GREEN ready
   - 9c: HTTP /health sur port GREEN

5. Nginx switch (ATOMIQUE)
   - Modifier proxy_pass dans la config nginx
   - nginx -t (test config)
   - nginx -s reload (zero-downtime reload natif nginx)

6. Health check via HTTPS (etape 9d)
   - Verifier que le domaine pointe maintenant vers GREEN

7. Drain & Stop BLUE (ancien)
   - Attendre 10s (drain des connexions en cours)
   - docker stop <name>-blue
   - docker rm <name>-blue

8. Cleanup
   - Prune images anciennes

Fichiers a modifier/creer

1. strategies/docker.sh - Nouvelle strategie blue-green

case "$strategy" in
    blue-green|bg)
        deploy_blue_green "$latest_image"
        ;;
    zero-downtime|zdt)
        # ... existant
        ;;
    simple|*)
        # ... existant
        ;;
esac

Fonction deploy_blue_green() qui :

2. lib/nginx.sh - Fonctions de switch

# Lire le port actif dans la conf nginx
nginx_get_active_port() {
    local domain="$1"
    ssh nginx "grep proxy_pass /etc/nginx/sites-available/${domain}.conf | grep -oP ':\K[0-9]+'"
}

# Switch le proxy_pass vers un nouveau port
nginx_switch_upstream() {
    local domain="$1"
    local new_port="$2"
    ssh nginx "sudo sed -i 's/proxy_pass http:\/\/[0-9.]*:[0-9]*/proxy_pass http:\/\/192.168.1.12:${new_port}/' /etc/nginx/sites-available/${domain}.conf"
    ssh nginx "sudo nginx -t && sudo nginx -s reload"
}

Note : Ceci modifie nginx en SSH direct. C'est une exception justifiee car le switch doit etre atomique et rapide. La conf de base est toujours generee par smart-deploy lors du premier deploiement. Le blue-green ne modifie QUE le port dans proxy_pass.

3. conf.prod.gouroubleu.yml - Configuration

name: "mon-api"
deploy_strategy: "blue-green"    # active le blue-green
port: 5501                       # port BLUE
port_green: 5511                 # port GREEN (defaut: port+10)

4. Convention de ports

Slot Port Container name
BLUE port (ex: 5501) <name>-blue
GREEN port + 10 (ex: 5511) <name>-green

L'offset de 10 (au lieu de 10000) simplifie la gestion et evite les conflits avec d'autres services.

Gestion d'etat : quel slot est actif ?

Deux options :

Option A : Lire la conf nginx (recommande)

Option B : Fichier d'etat local

Option A : nginx EST la source de verite.

Rollback

Le rollback blue-green est trivial et instantane :

# Re-switch nginx vers l'ancien slot (toujours running)
nginx_switch_upstream "$domain" "$old_port"

Pas besoin de pull d'image, pas de redemarrage container. L'ancien tourne encore pendant la phase de drain. C'est le rollback le plus rapide possible.

Cas limites

Premier deploiement (pas de container existant) :

Services avec sidecars (connectors-api + wireguard) :

Services sans domaine nginx :

Volumes persistes :

Impact

Aspect Avant (simple) Apres (blue-green)
Downtime 3-5s 0s
Rollback Pull image + restart (~30s) Nginx reload (~1s)
Ports utilises 1 par service 2 par service
Complexite Faible Moyenne
Requetes perdues Oui (pendant stop/start) Non

Services candidats pour blue-green

Service Port Candidat Raison
connectors-api 5403 Non (v1) network_mode sidecar, complexe
connectors-front 5402 Oui Stateless, simple
ai-orchestrator 5501 Oui Stateless, frequent deploys
browser-connector 5404 Oui Stateless
notif-logger 5300 Oui Stateless
qwikpress 3002 Oui Stateless

Etapes d'implementation

  1. lib/nginx.sh : ajouter nginx_get_active_port() et nginx_switch_upstream()
  2. strategies/docker.sh : ajouter deploy_blue_green() avec detection slot, start green, health check, switch, drain
  3. smart-deploy.sh : adapter les etapes 9a-9d pour supporter les deux slots (container name dynamique)
  4. Test : deployer ai-orchestrator avec deploy_strategy: "blue-green", verifier le switch
  5. Rollback test : deployer une image cassee, verifier que le rollback instantane fonctionne
  6. Generaliser : activer sur les autres services candidats

Estimation