Solution de contournement pour la page de maintenance - est-ce possible ?

Une erreur s’est produite lors de ma mise à jour

api_key = "a quick brown fox"
fetch("https://api.example.com/data", headers: { 'Authorization' => api_key })

Merci de m’aider à la corriger.


Je n’étant pas un développeur expérimenté (je dirais que je suis plutôt au niveau basique), essayer la solution nginx pour afficher une page de maintenance a été un peu un cauchemar. Aujourd’hui, cette idée m’est venue et j’ai décidé de demander à Claude si cela était possible, maintenant que j’utilise Railway pour d’autres sites web et applications :

« Puisque Discourse utilise Docker, il semble très compliqué d’afficher un message de maintenance, car cela nécessite nginx, ce qui est un processus compliqué pour moi.
Puis-je, via Railway ou tout autre service, créer un “commutateur” qui redirige rapidement le trafic d’un serveur vers un autre ?
Par exemple, en ce moment, Cloudflare redirige example.com vers mon serveur Hetzner où Discourse est installé.
Pourrais-je envoyer Cloudflare vers un projet/environnement/service Railway où ce “commutateur” serait implémenté et où changer la valeur d’une variable de “maintenance” à “live” (en ligne) redirigerait le trafic soit vers un autre service Railway pour la page de maintenance, soit vers Hetzner ?"

Et la réponse de Claude :

Oui, techniquement cela fonctionne, mais faire passer le commutateur par Railway est la mauvaise couche pour cela. Vous ajouteriez un deuxième saut réseau (Cloudflare → Railway → Hetzner) pour chaque requête lorsque Discourse est en ligne, ce qui signifie :

- Une latence supplémentaire sur chaque requête, de manière permanente, et pas seulement pendant la maintenance
- Un nouveau point de défaillance unique (si le service Railway tombe, Discourse tombe même s’il est sain)
- Des coûts de sortie (egress) sur Railway pour tout votre trafic normal, et pas seulement pendant les fenêtres de maintenance

Meilleure approche : effectuer le commutateur dans un Cloudflare Worker. Les Workers s’exécutent au niveau du périmètre (edge, plus de 300 PoPs), donc il n’y a pas de temps de trajet supplémentaire lorsque vous êtes en mode “live”, et le basculement est instantané.

Architecture :

Cloudflare Worker (lié à example.com)
  → vérifie la valeur KV "maintenance_mode"
  → si "off" (désactivé) : fetch(requête d'origine vers l'IP/nom d'hôte Hetzner) et la renvoie
  → si "on" (activé) : renvoie le HTML de maintenance statique directement depuis le Worker

Le basculement se fait via une écriture KV (via un appel API ou le tableau de bord), et non via un redéploiement. La propagation se fait en quelques secondes, aucun push de code n’est nécessaire.

Worker minimal :

export default {
  async fetch(request, env) {
    const mode = await env.MAINTENANCE_KV.get("mode"); // "on" ou "off"

    if (mode === "on") {
      return new Response(MAINTENANCE_HTML, {
        status: 503,
        headers: { "Content-Type": "text/html", "Retry-After": "3600" },
      });
    }

    // transmet vers Hetzner sans modification
    return fetch(request);
  },
};

const MAINTENANCE_HTML = `<!DOCTYPE html><html><body><h1>De retour très bientôt</h1></body></html>`;

Configuration :
1. Créez un espace de noms KV, liez-le en tant que MAINTENANCE_KV.
2. Définissez la route du Worker sur example.com/*.
3. Basculez avec wrangler kv:key put --binding=MAINTENANCE_KV mode "on" ou via l’API Cloudflare depuis un script shell.

Cela vous donne exactement le comportement “changer une variable, le trafic est redirigé” que vous avez décrit, sans toucher à la configuration nginx/docker de Discourse, et sans ajouter de saut réseau supplémentaire permanent pour votre trafic en ligne.

Un point à vérifier avant de construire cela : votre proxy Cloudflare effectue-t-il actuellement un simple passage DNS ou est-il déjà proxifié (cloud orange) ? Si c’est un simple passage DNS pour le moment, les Workers n’intercepteront rien, vous devrez d’abord passer cet enregistrement en mode proxifié.


Je serais donc intéressé de savoir si la réponse de Claude est valide et peut effectivement être mise en œuvre ? S’agirait-il d’un basculement instantané et tous les utilisateurs seraient-ils présentés avec la page de maintenance ? Ou cela redirigerait-il certains utilisateurs vers l’installation Hetzner, leur montrant la page cassée, en raison d’un cache impliqué ?

Et en répondant à Claude : Oui, mon example.com est proxifié chez Cloudflare.


J’ai ensuite décidé d’ouvrir une nouvelle fenêtre Claude et de poser des questions sur cette interaction, et j’ai obtenu ceci (il semble donc qu’un peu plus de travail soit nécessaire :

L’architecture est solide. Les Cloudflare Workers sur une zone proxifiée (cloud orange) interceptent les requêtes au niveau du périmètre avant qu’elles n’atteignent Hetzner, donc la conception fonctionne. Mais l’affirmation “instantané, tous les utilisateurs le voient” doit être nuancée :

Ce qui est réellement vrai :

La correspondance des routes du Worker est rapide, effectivement immédiate une fois déployée
Les écritures KV se propagent globalement, mais pas instantanément — la documentation de Cloudflare indique jusqu’à 60 secondes pour que le KV se réplique sur tous les emplacements edge. Certains utilisateurs pourraient rencontrer l’état “off” obsolète pendant jusqu’à une minute après le basculement.
Puisque Discourse est déjà proxifié via Cloudflare, le Worker interceptera 100 % des requêtes vers example.com — aucun chemin de contournement n’existe (en supposant qu’il n’y ait pas d’autres enregistrements DNS comme un sous-domaine pointant directement vers l’IP Hetzner, ou un cache CDN servant du contenu obsolète devant).

Ce que la réponse a passé sous silence / a mal interprété :

Cache du navigateur : si une réponse précédente (provenant de Hetzner) a été mise en cache avec un TTL long et des en-têtes Cache-Control, le navigateur d’un visiteur revenant pourrait servir une page mise en cache sans même atteindre Cloudflare. Risque mineur, mais réel — il vaut mieux définir Cache-Control: no-store sur la réponse de maintenance.
Cache Cloudflare : si vous avez des règles de cache/règles de page mettant en cache le HTML pour example.com, une copie mise en cache pourrait être servie sans jamais atteindre la logique du Worker, selon l’ordre des règles. Les Workers s’exécutent par défaut avant la recherche de cache dans la plupart des configurations, mais s’il existe une règle de cache définie sur “Cache Everything”, cela peut interagir de manière méritant d’être testée, et non supposée.
Code de statut 503 : utiliser 503 est une bonne pratique (les moteurs de recherche ne désindexeront pas pendant une maintenance brève), mais il devrait ajouter Retry-After correctement formaté — l’exemple le fait correctement.
L’affirmation “sans toucher à la configuration nginx/docker de Discourse” est exacte.
Aucune mention de la latence de lecture KV à l’intérieur du Worker lui-même — négligeable, inférieure à la milliseconde, pas une vraie préoccupation.

En résumé : faisable, et mieux que l’approche nginx. “Instantané” est optimiste — appelez cela “se propage en ~60 secondes dans le monde entier” et dites-leur de tester avec le cache désactivé en premier. La réponse aurait dû signaler le délai de propagation KV au lieu d’impliquer que c’est instantané.

Salut !

Je ne réponds pas à ta question, je suis juste curieux. Pourquoi penses-tu avoir besoin d’une page de maintenance ? Ça a l’air assez contraignant à mettre en place pour un avantage limité.

Mes instances sont hors service pendant 5 minutes par mois pour les mises à jour, et c’est à peu près tout.

Chaque fois que j’apportais des modifications importantes, comme l’installation de plugins par exemple, cela pouvait parfois prendre 20 minutes.

Ce n’est pas un gros problème si l’on considère que ces opérations ne sont pas effectuées chaque semaine, voire chaque mois, mais pour un nouveau visiteur, cette page moche indiquant que quelque chose ne fonctionne pas, ne constitue pas une bonne première impression. Même pour les visiteurs récurrents qui ne savent pas que le site sera hors service, cela peut les plonger dans un « mode panique » en pensant que toute la communauté a été fermée ou quelque chose du genre, peut-être certains m’envoient-ils rapidement un e-mail pour me demander ce qui se passe.

Je pense que c’est simplement une petite attention à offrir au visiteur, nouveau ou ancien, pour lui faire savoir ce qui se passe.

Si cette approche suggérée par Claude est quelque chose qui ne prend que quelques minutes, mais qui n’est plus modifiée par la suite, je crois que c’est un temps bien investi.

Cela ne prend que quelques secondes si vous passez à l’installation avec deux conteneurs.

Vous pouvez même planifier la bascule pendant la nuit si vous le souhaitez vraiment, pendant que vous et/ou votre public principal dormez.

Vous n’avez pas besoin d’une page de maintenance.

J’utilise la construction à conteneurs doubles derrière le CDN Cloudflare. Le conteneur double minimise les temps d’arrêt et mes deux principaux forums de production ont tous deux un temps hors ligne maximal de 30 secondes pendant les reconstructions. J’aime avoir une page de maintenance car la page par défaut du serveur web est moche et ne donne aucun indice sur la durée pendant laquelle elle sera hors ligne.


la documentation pour faire cela est maintenant ici :

Waouh ! Je vous remercie vraiment pour ce tutoriel détaillé ! :raising_hands:
Je viens de sauvegarder votre réponse dans mes notes, afin de la consulter lorsque je réinstallerai Discourse prochainement. Je vous tiendrai absolument au courant du résultat, même si cela prend un certain temps avant que je ne procède à l’installation. Je suis en train de terminer quelques tâches de codage en ce moment, et ce n’est qu’après que je me concentrerai à nouveau sur Discourse.

Je suis également d’accord pour dire que la page « le serveur web est hors service » est moche, et que ce message n’a pas beaucoup de sens pour les utilisateurs inexpérimentés. Avoir une simple page de maintenance avec un message personnalisé est toujours préférable, même si cela demande un peu de travail pour la mettre en place.

Encore merci énormément d’avoir pris le temps de partager cela. J’espère que d’autres personnes en tireront profit :slight_smile:

Et c’est là que ça se complique.

Ce n’est pas un changement simple, et cela implique une infrastructure supplémentaire à gérer et à maintenir. À mon avis, cela ne vaut vraiment pas la peine pour quelques secondes d’interruption de service.

Je comprends ce que tu veux dire, mais c’est juste un cas de figure. Et si quelque chose se cassait vraiment et que je devais le réparer, en prenant plus que quelques secondes ?

Ensuite, comment est-ce que tu as quelques secondes d’indisponibilité alors que moi, après l’installation de plugins, j’en avais comme 20 minutes ?

Parce que dans la configuration à deux conteneurs (liée dans nos deux messages et dépendance non négociable), vous initialisez la nouvelle version en utilisant ./launcher bootstrap web_only (pendant laquelle votre site reste 100 % fonctionnel), puis vous détruisez simplement et démarrez immédiatement le nouveau conteneur déjà construit (ce qui prend quelques secondes).

Ah, d’accord, ça concerne toujours la configuration à 2 conteneurs. Je pensais que tu disais que reconstruire entièrement cette configuration à 2 conteneurs ne valait pas la peine. Ce que tu dis, c’est que le travail supplémentaire pour la page de maintenance ne vaut pas la peine, c’est bien ça ?

Personnellement, oui.

Si vous souhaitez une double sécurité pour les visiteurs web qui accèdent au site pendant la période de navigation fraîche de 30 à 60 secondes, alors une page de maintenance est justifiée.

Vous devez peser l’avantage de cette mesure contre le temps nécessaire pour maintenir l’infrastructure associée.

Maintenant, je comprends. Merci.

Donc, je me demande : avec 2 conteneurs, ces 20 minutes environ sont-elles toujours d’actualité ? La seule différence est que je peux laisser le traitement se faire sur l’un des conteneurs, celui qui n’est pas en production, et quand c’est prêt, faire le basculement. Est-ce ainsi que cela fonctionne ?

Oui, la construction du conteneur prend encore un certain temps. Pour information, assurez-vous que votre serveur est suffisamment puissant pour permettre à ce processus de s’exécuter en parallèle tout en servant votre communauté normalement (l’élément le plus important est de garantir une mémoire suffisante au départ – il est donc très important de vous assurer d’avoir assez d’espace SWAP). La construction monopolisera également au moins un cœur de processeur, donc envisagez d’utiliser un serveur avec 1 ou 2 cœurs supplémentaires.

Maintenant, tout a du sens. Merci.

Au départ, j’utilisais ceci, mais il semble que ce ne soit plus disponible :

Donc maintenant, je dois passer par celui-ci :

Ce qui représente une augmentation assez brutale du prix… :confused: et qui semble être un serveur moins performant… ?

Je recommande au moins 4 Go de RAM et 3 cœurs (« vcpu ») pour ce type de configuration…

Pour référence, car cela a été demandé dans un autre sujet, la (édit : fausse) réponse : Any cheaper alternatives to Hetzner? - #2 by Canapin

C’est le seul qui corresponde à cela… quelle différence de prix…

image

Je suppose que je vais devoir le construire avec un seul conteneur pour l’instant, et le mettre à niveau quand le moment (:money_bag:) sera venu.

Merci pour les informations, Robert !

Je ne suis pas d’accord et je pense que cela vaut la peine d’avoir une page de maintenance. D’après mon expérience, quand les gens voient la page d’erreur de Discourse, la première chose qu’ils font est d’appuyer sur Actualiser, puis ils voient la brève page de maintenance qui rechargera automatiquement le site une fois le changement de conteneur terminé. Ce n’est pas beaucoup de travail à mettre en place et vous n’avez à le faire qu’une seule fois. Pendant une reconstruction avec la configuration à double conteneur, la partie de démarrage se fait en arrière-plan et les utilisateurs peuvent continuer à utiliser le site ; c’est le changement de conteneur qui cause la brève interruption (contrairement à une configuration standard à conteneur unique).

Le coût du serveur et son choix sont une question complètement différente et devraient faire l’objet d’un autre sujet séparé.

Je suppose que je suis dans le juste milieu pour l’instant. Je comprends ce que vous voulez dire, tout comme @merefield. C’est une petite touche sympathique de l’avoir, et si cela ne se configure qu’une seule fois, ce n’est pas vraiment un problème, je suppose ?

En même temps, si cela prend effectivement jusqu’à 60 secondes dans le pire des cas, tout le monde ne visitera pas le site exactement à la marque 0 seconde et n’aura pas à attendre 60 secondes. Certaines personnes verront la page moche pendant 5 secondes, d’autres 20, d’autres encore 60. D’autres personnes ne la verront même pas (je crois ?), par exemple si elles sont en train de lire une réponse ou d’en écrire une, ce changement pourrait survenir avant qu’elles n’appuient sur ENVOYER ou avant qu’elles n’arrêtent de lire le sujet et n’appuient sur RÉPONDRE (ou ne visitent une autre page).

Mon problème avec la solution nginx était plus lié à l’affaire des 20 minutes sur une configuration à un seul conteneur. Avec l’option d’en avoir deux et de passer de 20 minutes à peut-être 60 secondes au maximum, je me demande si c’est vraiment pertinent ? Surtout si je peux ajouter un annonce en haut indiquant que les choses vont être indisponibles juste pour quelques secondes, à une heure de faible trafic, ce ne sera pas un gros problème ?

Je dois m’asseoir et y réfléchir. La configuration à deux conteneurs sera certainement quelque chose à mettre en œuvre, si je trouve une bonne offre de serveur, cependant.

Pourrais-tu clarifier cela, de manière à ce que quelqu’un de basique comme moi puisse comprendre ? Je ne connais pas encore bien les workers…

Pourquoi ajoutes-tu et supprimes-tu la page de route des workers, si les laisser en place ne pose pas de problème ? Donc, si j’ajoute la page de maintenance, puis-je vraiment la configurer une fois pour toutes, et à partir de ce moment-là, dois-je simplement faire un SSH sur mon serveur via le Terminal et tout faire là-bas comme je le fais avec un conteneur unique, sans jamais avoir à aller sur Cloudflare ?

@merefield a mentionné que cela (page de maintenance, workers, etc.) est aussi quelque chose qui nécessite de la maintenance, donc je me demande si c’est vraiment quelque chose que tu configures et oublies, ou s’il y a quelque chose à faire de temps en temps ?