Déployer sans interruption avec une vérification d’état, et ce que Canner fait aujourd’hui.
Un déploiement sans interruption démarre la nouvelle version à côté de l’ancienne, ne lui envoie du trafic qu’après une vérification d’état réussie, puis envoie SIGTERM à l’ancienne pour qu’elle termine ses requêtes. Canner vérifie chaque déploiement et laisse 30 secondes à l’ancien processus, mais l’arrête avant de démarrer le nouveau : prévoyez une courte coupure.
Faits vérifiés le
Ce qu’un point de terminaison /health doit renvoyer
Des codes d’état, pas un contenu. Le vérificateur de chaque plateforme lit le statut HTTP. Un 200 veut dire « envoyez-moi du trafic », un 5xx veut dire « pas encore ». Le JSON est pour vous, quand vous lancez curl.
Kubernetes nomme bien les deux questions. Une sonde de disponibilité (readiness) demande si l’appli peut recevoir du trafic maintenant; une sonde d’activité (liveness) demande si elle est bloquée et doit être redémarrée. La vérification d’un déploiement est une sonde de disponibilité : elle doit échouer quand l’appli ne peut pas faire son travail, par exemple sans accès à sa base de données, et réussir sinon.
- Rapide. Répondez en bien moins d’une seconde. Canner attend au plus 3 secondes par tentative.
- Sans authentification ni redirection. Exemptez le chemin de la connexion, des redirections HTTPS et des limites de débit.
- Vérifiez ce dont l’appli ne peut pas se passer. Un
select 1sur la base détecte unDATABASE_URLerroné au déploiement plutôt qu’au premier visiteur. - Ne vérifiez pas ce dont elle peut se passer. Si une API externe tombe, faire échouer votre vérification d’état fait tomber toute l’appli avec elle.
// Express. Fast, unauthenticated, no redirects.
app.get("/healthz", async (req, res) => {
try {
await pool.query("select 1"); // can we reach the database?
res.status(200).json({ ok: true });
} catch {
res.status(503).json({ ok: false }); // 5xx = not ready
}
});Comment la vérification d’état de Canner lit votre réponse
Ces détails viennent du code de la plateforme, et ils changent ce que votre point de terminaison doit faire.
- Elle interroge le chemin de vérification (
/, sauf si vous en indiquez un autre dans les paramètres du projet) toutes les demi-secondes pendant au plus 30 secondes après le démarrage du nouveau processus. - Tout statut sous 500 passe. Un
200, un302vers une page de connexion et un404veulent tous dire « le serveur répond ». Une faute de frappe dans le chemin passe quand même : votre vérification de la base ne compte que si le chemin existe vraiment. - Un
5xxla fait réessayer jusqu’à la fin des 30 secondes, puis le déploiement échoue avec le dernier statut dans le journal. C’est ainsi qu’un503du point de terminaison ci-dessus arrête un déploiement qui n’atteint pas sa base. - Elle envoie
X-Forwarded-Proto: httpset ne suit jamais les redirections : une appli qui impose HTTPS (Rails 7.1+,SECURE_SSL_REDIRECTde Django) n’est pas prise pour une appli en panne. - Une fois la vérification réussie, Canner surveille le processus encore 10 secondes. Une appli qui répond une fois puis plante, à cause d’un secret manquant lu plus tard par exemple, fait échouer le déploiement au lieu de passer en ligne et de renvoyer des 502.
- Les projets déployés comme worker sautent la vérification HTTP; ils doivent seulement rester en marche.
Ce qui se passe pendant un déploiement Canner, dans l’ordre
Canner ne fait pas encore tourner l’ancienne et la nouvelle version côte à côte; les emplacements de déploiement bleu-vert, qui le permettront, sont dans notre feuille de route. Aujourd’hui, un déploiement en production se déroule ainsi :
- La compilation roule dans son bac à sable. Votre site n’est pas touché.
- La commande de mise en production s’exécute, si vous en avez une, pendant que l’ancienne version sert encore. Si elle échoue, le déploiement s’arrête là et rien ne change.
- L’ancien processus reçoit SIGTERM et dispose d’au plus 30 secondes pour finir ses requêtes. Ensuite, SIGKILL.
- Le nouveau processus démarre sur le même port, passe la vérification d’état, puis est surveillé 10 secondes.
- S’il réussit, le déploiement est en ligne. S’il échoue, Canner l’arrête et, avec le retour arrière automatique activé, recompile votre dernier bon commit et le déploie.
Comment les autres plateformes changent de version
La différence qui compte : l’ancienne et la nouvelle version se chevauchent-elles? Le reste, c’est du réglage.
| Plateforme | Chevauchement ancienne/nouvelle? | Signal d’arrêt | Délai avant l’arrêt forcé |
|---|---|---|---|
| Canner | Non : l’ancienne est arrêtée, puis la nouvelle démarre | SIGTERM | 30 s |
| Render † | Oui : l’instance d’origine garde tout le trafic pendant que la nouvelle démarre | SIGTERM | 30 s par défaut, jusqu’à 300 s |
| Heroku (par défaut) † | Non : le preboot est désactivé à moins de l’activer | SIGTERM | 30 s |
| Heroku avec preboot † | Oui, environ 3 minutes au plus; sur demande, dynos Standard et Performance | SIGTERM | 30 s |
| Fly.io † | Progressif par défaut, une Machine à la fois; bluegreen exige au moins une vérification d’état | SIGINT par défaut | 5 s par défaut, jusqu’à 300 s |
† Les détails sur les concurrents proviennent des pages publiées par chaque fournisseur aux dates indiquées; les prix et forfaits changent, vérifiez auprès du fournisseur avant de décider. Render (2026-10-29) · Heroku (par défaut) (2026-10-29) · Heroku avec preboot (2026-10-29) · Fly.io (2026-10-29)
Arrêt en douceur sur SIGTERM
SIGTERM, c’est la demande polie. En le recevant, cessez d’accepter de nouvelles connexions, terminez ce qui est en cours, fermez les connexions à la base et quittez. Faites-le avant la fin du délai de grâce, parce que le signal suivant ne s’intercepte pas.
next start de Next.js installe son propre gestionnaire de SIGTERM. Un serveur Node ordinaire n’en a pas : sans gestionnaire, Node quitte immédiatement et coupe les requêtes ouvertes. Gunicorn (Python) et Puma (Ruby) le gèrent à leur façon; vérifiez que votre commande de démarrage lance le serveur directement (exec) et non derrière un shell qui avale le signal.
const server = app.listen(process.env.PORT);
process.on("SIGTERM", () => {
// Stop accepting connections, let in-flight requests finish.
server.close(async () => {
await pool.end(); // close database connections
process.exit(0);
});
// Leave before the platform's SIGKILL (30 s on Canner).
setTimeout(() => process.exit(1), 25_000).unref();
});Les changements de base qui cassent l’ancien code
Même avec un chevauchement parfait, un déploiement n’est pas sans interruption si la migration casse la version encore en marche. Chez Canner, la commande de mise en production s’exécute pendant que l’ancienne version sert; sur les plateformes à chevauchement, l’ancienne et la nouvelle tournent ensemble sur un même schéma. Dans les deux cas, l’ancien code rencontre le nouveau schéma.
Renommer ou supprimer une colonne que l’ancien code lit fait échouer ses requêtes jusqu’à ce que la nouvelle version prenne le relais. Étalez ces changements sur deux déploiements : ajouter d’abord, retirer ensuite. Où exécuter les migrations détaille les étapes, et explique pourquoi désactiver le retour arrière automatique pour un déploiement dont la migration ne convient pas au commit précédent.
L’état en mémoire est l’autre piège. Les sessions, compteurs de limite de débit et caches gardés dans la mémoire du processus disparaissent à chaque déploiement. Gardez les sessions dans des témoins signés ou dans votre base Postgres.
Questions
Que doit renvoyer un point de terminaison de vérification d’état?
Un 200 quand l’appli peut servir des requêtes et un 503 quand elle ne le peut pas, en bien moins d’une seconde, sans connexion ni redirection devant. Vérifiez la base dont elle dépend; pas les API externes facultatives.
Quelle est la différence entre liveness et readiness?
La sonde de disponibilité (readiness) demande si l’appli doit recevoir du trafic maintenant; en échec, elle est retirée de la rotation. La sonde d’activité (liveness) demande si elle est bloquée; en échec, elle est redémarrée. La vérification d’un déploiement est une sonde de disponibilité.
Les déploiements chez Canner sont-ils sans interruption?
Pas encore. Canner arrête l’ancien processus (SIGTERM, au plus 30 secondes) avant de démarrer le nouveau : les requêtes pendant le changement reçoivent un 502. Il vérifie l’état de la nouvelle version et revient en arrière si elle échoue. Des emplacements bleu-vert qui superposent les deux versions sont dans la feuille de route.
Pourquoi mon déploiement passe la vérification d’état alors que le site affiche des erreurs?
Chez Canner, tout statut sous 500 passe : un 404 ou une redirection vers la connexion comptent comme en santé. Pointez le chemin de vérification vers un point de terminaison qui vérifie vraiment la base, et consultez les Journaux pour les erreurs derrière la page.
Combien de temps une appli a-t-elle pour s’arrêter?
30 secondes chez Canner, Heroku et Render par défaut, ainsi que dans Kubernetes par défaut. Fly.io accorde 5 secondes par défaut. Ensuite, le processus est tué.
Déployez avec une vérification d’état qui veut dire quelque chose.
Chaque déploiement Canner est vérifié, surveillé contre les plantages et annulé s’il échoue. La configuration pour chaque cadriciel est dans Hébergement par cadriciel.