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

Oui, je le ferai par étapes :

  1. obtenir un serveur légèrement plus puissant
  2. faire fonctionner l’installation des deux conteneurs

si à ce stade tu es satisfait, arrête-toi ici, ou :

  1. mettre en place la page de maintenance en utilisant l’excellent guide de @Lilly ci-dessus. :+1:

Haha, je suis ravi que tu aies posé la question, car je n’avais pas pris le temps d’expliquer cette partie (j’aurais dû – il y a beaucoup de choses à expliquer et Cloudflare est complexe !)

Lorsque la page de route des workers est configurée, chaque chargement d’image et chaque consultation de page sur le forum est acheminé via ce worker.

Le plan CDN gratuit de Cloudflare inclut une limite de 100 000 requêtes/jour sur une route de worker.

Ainsi, si vous avez un forum relativement actif, afin d’éviter d’atteindre la limite de votre offre gratuite en une seule journée, il est judicieux de ne pas la laisser activée en permanence. Il s’agit uniquement de la route du worker, et non de la page de maintenance – vous pouvez laisser la page de maintenance en place en permanence – elle n’est sollicitée que si vous avez activé la route du worker. Il s’agit simplement de l’étape 2 où vous avez assigné la route (ce qui est facile à configurer et à supprimer). À moins que vous n’utilisiez un plan payant de Cloudflare, il est donc de bonne pratique de ne l’activer que lorsque vous effectuez votre propre maintenance.

  1. Rendez-vous sur la page des routes des workers Cloudflare pour votre domaine et cliquez sur le bouton situé à droite de la route.

  1. En bas de l’écran de modification, cliquez sur le bouton remove pour détacher la page du worker de la route.

  1. Ne vous inquiétez pas, le code du worker lui-même ne sera pas supprimé, uniquement la règle de routage. La prochaine fois que vous effectuerez une reconstruction / mise à jour, vous pourrez simplement la réajouter comme dans l’étape 2 ci-dessus.

Si vous utilisez un plan payant Cloudflare, alors vous n’avez rien à craindre. Cependant, dans ce cas, vous pouvez utiliser les pages d’erreur Cloudflare au lieu d’une page de worker… (ai-je déjà mentionné que Cloudflare est assez complexe ? LOL)

:warning: configuration avancée pour administrateur ci-dessous

Si l’on souhaite automatiser complètement ses mises à jour sur le plan gratuit, il faut utiliser un jeton API Cloudflare, son identifiant de zone et une commande curl pour obtenir l’identifiant de la route du worker. Ensuite, modifiez le script /root/update-web.sh avec quelques fonctionnalités supplémentaires pour activer et désactiver automatiquement la route du worker :

#!/bin/bash
cd /var/discourse

CF_TOKEN="votre_vrai_jeton_ici" #<---Jeton API Cloudflare
ZONE_ID="xxxx" #<---Depuis votre page de profil Cloudflare
ROUTE_ID="xxxx"
WORKER_NAME="ma-page-de-maintenance-site"

echo "➡️ Téléchargement des derniers scripts Docker Discourse..."
git pull

echo "➡️ Initialisation du nouveau conteneur web en arrière-plan..."
./launcher bootstrap web_only

if [ $? -eq 0 ]; then
    echo "✅ Initialisation réussie !"
    
    # Activer le Worker de Maintenance Cloudflare
    echo "🚧 Activation de la page de maintenance..."
    curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/workers/routes/$ROUTE_ID" \
         -H "Authorization: Bearer $CF_TOKEN" \
         -H "Content-Type: application/json" \
         --data '{"pattern":"*votre-site.com/*","script":"'$WORKER_NAME'"}' > /dev/null

    # Échanger les conteneurs (Fenêtre d'indisponibilité de 30 secondes)
    echo "🔄 Échange des conteneurs..."
    ./launcher destroy web_only && ./launcher start web_only
    
    # Désactiver le Worker de Maintenance Cloudflare
    echo "🌍 Désactivation de la page de maintenance..."
    curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/workers/routes/$ROUTE_ID" \
         -H "Authorization: Bearer $CF_TOKEN" \
         -H "Content-Type: application/json" \
         --data '{"pattern":"*votre-site.com/*","script":null}' > /dev/null

    echo "🚀 Terminé ! Site mis à jour avec une indisponibilité invisible.
else
    echo "❌ Échec de l'initialisation ! Abandon de l'échange pour garder le site actuel en ligne."
fi 

J’utilise la version précédente du script car je ne souhaite pas tout automatiser et j’aime être présent lors des mises à jour / reconstructions. J’ajoute simplement la route du worker juste avant de faire une mise à jour, puis je la supprime ensuite. Cela ne prend que quelques secondes.

Mes étapes générales sont :

  1. Ajouter la route du worker sur Cloudflare
  2. Se connecter en SSH à Hetzner
  3. Effectuer les mises à jour système (par exemple : sudo apt update && sudo apt upgrade -y, puis redémarrer le serveur si nécessaire)
  4. Se reconnecter en SSH si un redémarrage était nécessaire
  5. Exécuter ./update-web.sh
  6. Supprimer la route du worker sur Cloudflare

Je ne connais rien au codage et au monde du développement, si ce n’est que j’ai fait un petit programme « Hello World » avec Visual Basic il y a très longtemps. Mais je peux faire certaines choses, car je sais mieux administrer mes serveurs WordPress et Mastodon/Pixelfed, et d’une manière ou d’une autre, mon instance Discourse. Par ailleurs, il existe cet outil nommé IA (qui n’est pas aussi simple pour un débutant que ce qu’on en dit dans la publicité).

Je ne sais pas si c’est même possible avec Discourse à cause de Docker, mais dans l’univers classique Nginx-Varnish-WordPress, j’ai mis en place un système où un serveur Plesk reçoit les informations sur les erreurs 50x et affiche une page d’erreur. En réalité, j’ai trois configurations : le frontend Nginx affiche le contenu d’une capture générée si Varnish est hors service ; Varnish utilise la capture pour le contenu non mis en cache lorsque le backend lié à WordPress est hors service ; et la troisième est une page d’erreur si le frontend Nginx ne répond pas.

Les manipulations avec Varnish ne sont pas possibles pour Discourse, mais je ne vois aucune raison pour laquelle on ne pourrait pas construire une telle toile d’araignée dans l’univers Docker, où toute erreur 50x afficherait une page d’erreur.

Ce système pourrait toutefois être très sujet aux erreurs. Et je n’ai aucune idée de ce qui se passerait s’il y avait plus qu’une poignée d’utilisateurs.

Il y a aussi la réponse la plus évidente, bien sûr : placer par exemple Nginx devant Discourse. J’utilisais cette configuration avant de passer à deux conteneurs.

J’ai enfin pris le temps de réinstaller Discourse. Après avoir évalué ma situation actuelle et la quantité d’entretien que semblent nécessiter deux conteneurs, je pense que je vais m’en tenir à un seul pour le moment. Si j’ai besoin de deux conteneurs à l’avenir, je réviserai tout ce qui est dit ici. À part l’installation de plugins, ce qui ne me semble pas être une tâche aussi fréquente que la gestion des composants, le fait que la communauté soit hors ligne pendant 20 minutes à une période de la journée où moins de personnes sont en ligne, accompagné d’une bannière informant les utilisateurs que la communauté sera indisponible à une date et une heure précises, me semble tout à fait raisonnable pour le moment.

On verra bien comment ça se passe.

Cela nécessite autant qu’un conteneur unique :flushed_face:

Et moins de chagrin :slight_smile:

Peux-tu préciser comment ça se passe ?

Je ne suis pas sûr que tu répondais à moi ou à @Jagster ? Que veux-tu dire ?

Car le processus de bootstrap du nouveau conteneur, tout en gardant votre site en ligne, est beaucoup moins stressant : si la construction échoue, vous n’avez pas à paniquer et vous disposez de tout le temps nécessaire pour la corriger sans rester hors ligne.

D’accord, donc vous encouragez à en avoir les deux, d’où l’expression « moins de douleurs ».
Donc, en tant que personne peu expérimentée en la matière, avoir 2 conteneurs ne signifie pas, je crois, deux instances de Discourse ?

Je lis le sujet

et

pour voir si je peux comprendre combien de travail cela demande et l’attention dont j’ai besoin, afin de ne pas me retrouver avec quelque chose que je ne peux pas gérer, rendant le processus plus problématique que toutes les autres choses qui peuvent mal tourner avec un seul.

Je tiens simplement à féliciter le partage concernant la configuration avec deux conteneurs. J’en utilisais un seul, et cela prenait généralement entre 3 et 5 minutes (sur un serveur dédié avec 64 Go de RAM).

Pourriez-vous m’expliquer, à travers des exemples clairs et simples, à quel moment il faut mettre à jour les deux conteneurs lors d’une installation double ? Autrement dit, quelles mises à jour de Discourse nécessitent un redémarrage des deux conteneurs, et lesquelles ne concernent que le conteneur web_container nouvellement créé ?

D’abord, vous suivez de très simples instructions pour démarrer le système à deux conteneurs. Ensuite, vous n’avez généralement besoin que de :

./launcher bootstrap web_only && ./launcher destroy web_only && ./launcher start web_only ) 2>&1 | tee ~/$(date +%Y-%m-%d_%H-%M-%S)-upgrade.log'

La partie tee sert uniquement à la journalisation, car c’est plus facile (pour moi) à parcourir que le flux tmux que j’utilise.

Mais en réalité, c’est exactement la même chose que l’utilisation de app.yml et la reconstruction, sauf que cela dérange beaucoup moins les utilisateurs. Certes, il y a un conteneur de données, mais il a très rarement besoin d’attention et de soins — et si vous faites des manipulations plus sophistiquées avec les conteneurs, vous savez probablement aussi quoi faire et quand avec les conteneurs.

Si la mise à niveau échoue avec le système à deux conteneurs, vous avez toujours un forum en ligne et fonctionnel, alors qu’un seul conteneur pourrait planter.

Donc, seule la phase de démarrage est un peu plus exigeante, mais les instructions sont assez claires. Je dirais que l’utilisation de mail-reveiver est une tâche plus difficile, surtout si vous utilisez Amazon SES.

Par exemple, c’est le genre de commentaire que je ne peux pas simplement ignorer, car il semble que la mise à jour/l’upgrade ne soit plus aussi simple qu’un simple clic sur un bouton, mais quelque chose qui nécessite plus d’attention et de concentration, ce qui peut sembler facile et évident à une personne expérimentée, mais peut-être pas à quelqu’un qui ne l’est pas :

Diriez-vous que les instructions de ce sujet sont toujours exactes en 2026, sachant qu’elles datent de 2015 ?

Je n’ai pas d’objection à essayer, puisque j’ai justement réinstallé Discourse aujourd’hui. Si ça ne marche pas, je pourrai toujours revenir à un seul conteneur. Je veux juste m’assurer de ne pas faire une erreur en cours de route qui ne serait plus valable en 2026…

L’économie de quelques minutes représente plus de 20 minutes pour moi. C’est vrai une fois par mois si l’on met à jour une fois par mois, mais je procède aux mises à jour au moins deux fois par semaine. Et si une extension échoue et qu’il faut faire plusieurs tentatives (car nous travaillons bien sûr avec des instances en production :wink:), cette longue interruption est simplement pénible.

Il n’y a pas de détails dans les annonces de chaque nouvelle version à suivre. Mcdanlj peut en avoir, mais il n’est pas un administrateur système ordinaire ; il opère à un niveau bien plus élevé.

Je suis perplexe…

Alors que tu dis :

ta réponse juste au-dessus laisse entendre qu’il y a plus de travail, quand tu dis :

Cela seul donne l’impression que deux conteneurs sont effectivement plus complexes à maintenir, et non équivalent à un seul ? Certes, je comprends la question du temps d’arrêt et tout le reste, mais la maintenance des conteneurs eux-mêmes semble plus complexe et plus sujette aux erreurs qu’une simple mise à niveau avec un seul conteneur. Ou est-ce que je rate quelque chose ?

c’est exact :

Conteneur 1 = site web & nginx
Conteneur 2 = base de données et redis

(je crois que c’est bien ça)

Le contenu du conteneur 1 change beaucoup

Le contenu du conteneur 2 change très rarement.

Et vous pouvez mettre à jour le conteneur 1 sans mettre à jour le conteneur 2.

Et mieux encore, vous pouvez préparer un remplacement pour le conteneur 1 puis le basculer en quelques secondes (la préparation s’appelle le « bootstrapping »)

Vous avez omis que, avec un conteneur unique, la commande ./launcher rebuild app arrête à la fois les parties web et données, puis les met à jour. Cependant, le côté données en a très rarement besoin, et après l’opération, tout est redémarré si aucun problème ne survient.

Avec deux conteneurs, vous ne reconstruisez que le conteneur « web », sans toucher au conteneur de données. Si tout se passe bien, l’ancien conteneur est détruit et un nouveau est démarré. En cas de problème, votre ancien conteneur « web », toujours fonctionnel, reste en service.

La seule différence réelle réside donc dans la manière de gérer le logiciel et quelques autres éléments liés à la base de données.

Bien sûr, une configuration à un seul conteneur est également une option. Mais le point principal est que, lorsqu’une configuration à deux conteneurs est créée, la seule vraie différence réside dans la commande utilisée lors de la mise à niveau — et pour cela, il existe l’alias :wink:

Cela a été écrit à l’époque des annonces manuscrites qui indiquaient qu’il était temps de mettre à jour la base de données. Le nouveau site automatisé est plus impressionnant, mais il n’y a plus de note humaine précisant ce qui est réellement le plus important, comme c’était le cas auparavant.

Aujourd’hui, je suppose qu’il faut remarquer un post indiquant que la base de données est en cours de mise à jour ? J’ai l’impression d’avoir manqué ces messages depuis des mois.

Cependant, cela n’arrive qu’une fois tous les quelques années, et la base est reconstruite lorsque vous effectuez explicitement une reconstruction, et CDCK semble avoir maintenu la compatibilité avec les anciennes versions de pgsql pendant un certain temps. Donc, cela ne m’a jamais vraiment posé de problème. Jusqu’à présent.

J’aime beaucoup la configuration à deux conteneurs (ou plus !) pour moi-même, mais je la présente toujours avec des réserves, car ce n’est pas la plus simple pour tout le monde. Il m’est difficile de juger pour qui le déploiement en deux conteneurs sera « bien sûr, c’est simple » et pour qui ce sera « oh, je veux juste appuyer sur un bouton ».