Sommaire
Sur un serveur unique, la façon la plus courante de déployer est aussi la plus brutale : docker compose up -d arrête l’ancien conteneur avant que le nouveau ne soit prêt. Pendant quelques secondes, parfois bien plus si des migrations tournent, les visiteurs reçoivent une erreur 502.
Cet article décrit une méthode qui tient en quarante lignes de configuration et ne demande ni Kubernetes ni service managé.
Le principe : deux couleurs
L’idée du déploiement bleu/vert est d’avoir deux instances de l’application. Une seule reçoit le trafic ; on met à jour l’autre, on vérifie qu’elle répond, puis on bascule le proxy. Si quelque chose se passe mal, l’ancienne version est toujours là.

Ce qu’il faut au minimum
- Une sonde de santé qui dit vraiment si l’application peut servir des requêtes
- Deux services Compose identiques, à un nom près
- Un fichier d’amont Nginx que l’on peut réécrire puis recharger
La sonde de santé
Une sonde qui répond toujours 200 ne sert à rien. Elle doit vérifier ce dont chaque requête a besoin : la base de données, et rien de plus coûteux.
export async function GET() {
try {
await db.execute(sql`SELECT 1`)
return Response.json({ status: 'ok' })
} catch {
return Response.json({ status: 'degraded' }, { status: 503 })
}
}Côté Compose, la sonde laisse le temps aux migrations de s’exécuter grâce à start_period :
services:
app-blue: &app
image: registry.example.com/site:${RELEASE}
healthcheck:
test: ['CMD', 'wget', '-qO-', 'http://127.0.0.1:3000/api/health']
interval: 5s
timeout: 3s
start_period: 60s
retries: 5
app-green:
<<: *appBasculer Nginx
Nginx lit la couleur active dans un petit fichier inclus. Le rechargement (nginx -s reload) termine les connexions en cours avec l’ancienne configuration : aucune requête n’est coupée.
# /etc/nginx/conf.d/upstream.conf, réécrit à chaque déploiement
upstream site {
server 127.0.0.1:3001; # app-green
keepalive 16;
}Le script complet
#!/usr/bin/env bash
set -euo pipefail
active=$(cat .active-color)
next=$([ "$active" = blue ] && echo green || echo blue)
docker compose up -d --wait "app-$next"
sed "s/app-$active/app-$next/" upstream.template > /etc/nginx/conf.d/upstream.conf
nginx -t && nginx -s reload
echo "$next" > .active-color
docker compose stop "app-$active"Un déploiement réussi est un déploiement dont personne ne s’aperçoit, sauf celui qui lit les journaux.
Les migrations, le vrai piège
Pendant la bascule, les deux versions tournent en même temps sur la même base. Une migration doit donc rester compatible avec la version précédente : on ajoute une colonne avant de l’utiliser, on arrête de l’utiliser avant de la supprimer.
- Déploiement 1 : ajouter la colonne, nullable
- Déploiement 2 : écrire dans les deux colonnes, lire la nouvelle
- Déploiement 3 : supprimer l’ancienne colonne
En vidéo
La démonstration complète, de la branche au serveur, en cinq minutes :
Pour aller plus loin
La documentation de Compose détaille l’option --wait et les conditions de santé ; celle de Nginx, le comportement du rechargement à chaud. Voir aussi notre liste de vérification de déploiement.
- #Docker
- #Observabilité



