Migrez rapidement vers des conteneurs web et de données séparés

:warning: Avertissement : Si vous n’êtes pas à l’aise en tant qu’administrateur système Linux et que vous n’avez pas d’expérience avec les conteneurs Docker, passer à un déploiement multi-conteneurs vous posera des difficultés. Le personnel et les bénévoles vous demanderont alors légitimement de revenir à un déploiement autonome à conteneur unique, entièrement géré par le script launcher.

Si vous passez à un déploiement multi-conteneurs et que votre système tombe en panne à la suite de cette opération, il est fort probable que vous vous retrouviez avec deux pièces cassées. Si, après avoir lu les instructions ci-dessous, vous avez l’impression que tout cela relève de la magie plutôt que de clarifier le fonctionnement réel à l’intérieur des conteneurs, fuyez vers votre déploiement autonome par défaut le plus proche. Cela vous évitera bien des ennuis.

La méthode recommandée pour migrer d’un déploiement à conteneur unique vers un déploiement multi-conteneurs consiste essentiellement à :

  • Sauvegarder votre Discourse
  • Tout jeter
  • Repartir de zéro avec un déploiement multi-conteneurs
  • Restaurer votre sauvegarde

Si, comme moi, vous avez un gros site qui prend des heures à restaurer, vous vous demandez peut-être s’il existe un moyen plus rapide. Ne vous posez plus la question ! J’ai migré d’un déploiement autonome vers un déploiement à trois conteneurs (web, données et Redis) en moins de temps qu’il ne faut généralement pour exécuter ./launcher rebuild app sur ce site. (12 minutes d’arrêt total, alors que la reconstruction de l’application prend parfois plus de 30 minutes.) D’après mon expérience, je garderais Redis avec Postgres dans un seul conteneur data à l’avenir.

Si vous faites cela, vous assumez la responsabilité de savoir quand vous devez reconstruire vos autres conteneurs (données, et Redis si, comme moi, vous êtes fou et que vous le séparez). Vous ne bénéficierez plus des mises à jour gratuites de l’ensemble avec ./launcher rebuild app — si vous n’avez pas les ressources nécessaires pour gérer ce processus, utilisez un déploiement autonome ou achetez un Discourse hébergé.

Test

N’utilisez pas ce processus pour migrer vers plusieurs conteneurs à moins que, après l’avoir lu, vous ne compreniez également comment il vous indiquerait comment migrer rapidement de plusieurs conteneurs vers un seul. Si cela ne vous semble pas évident après la lecture de ce texte, alors ce poste relève d’une technologie suffisamment avancée (c’est-à-dire indiscernable de la magie), et il est possible que vous ne reconnaissiez pas non plus si ce processus échoue en cours de route. Vous pourriez vous retrouver avec un Discourse cassé que vous ne remarquerez que beaucoup plus tard. Si cela arrive, vous garderez les deux pièces cassées. Vous le cassez, vous l’achetez, comme on dit !

Sauvegarde

Faites d’abord une sauvegarde et activez les sauvegardes de vignettes pour ne pas avoir à les reconstruire toutes lors de la restauration. Si vous faites une erreur ici, vous risquez facilement de vous retrouver dans une situation où la méthode la plus simple, la plus sûre et la plus rapide pour récupérer consiste à revenir à la méthode normale. Soyez prêt à revenir à la méthode recommandée si quelque chose tourne mal.

Téléchargez votre sauvegarde. Les commandes ci-dessous impliquent de déplacer des fichiers dans les données de Discourse, et si vous faites une erreur, vous aurez peut-être supprimé votre sauvegarde. Donc, téléchargez-la. Et, si votre sauvegarde ne comprend pas les uploads, sauvegardez-les également. Ils se trouvent également là où vous allez déplacer des fichiers.

Sérieusement, faites une sauvegarde.

Lorsque j’ai fait cela, j’ai d’abord fait une sauvegarde, puis une sauvegarde système à distance, avant d’aller plus loin.

Configurer la nouvelle configuration multi-conteneurs

Vous aurez besoin d’au moins containers/web_only.yml et containers/data.yml, et si vous souhaitez également séparer Redis, aussi containers/redis.yml. Commencez par copier samples/data.yml (et éventuellement samples/redis.yml) dans le répertoire containers/.

Si vous déployez Redis séparément, supprimez le modèle Redis du haut du fichier containers/data.yml. (Mais ne le faites pas sans une bonne raison ; ce n’est que du travail supplémentaire.)

Vous avez deux façons de créer web_only.yml.

  1. Copiez samples/web_only.yml dans containers/ ; puis comparez les deux avec containers/app.yml, en conservant toute configuration Postgres dans params: de votre nouveau containers/data.yml
  • Copiez tous les params: pour Postgres de containers/app.yml dans containers/data.yml
  • Créez un mot de passe unique pour remplacer SOME_SECRET
  1. Alternativement, copiez containers/app.yml dans containers/web_only.yml et comparez-le à samples/web_only.yml,
  • Supprimez toutes les références aux modèles Postgres et Redis
  • Supprimez la section params: entière qui ne contenait que les paramètres Postgres
  • Ajoutez une section links:, mot pour mot depuis samples/web_only.yml ou modifiée (voir ci-dessous) si vous déployez Redis dans un conteneur séparé
  • Ajoutez une section de base de données depuis samples/web_only.yml et créez un mot de passe unique pour remplacer SOME_SECRET
  • Modifiez les définitions de volumes de standalone à web_only

Voici la section links: à utiliser si vous séparez Redis dans son propre conteneur au lieu d’utiliser le choix par défaut raisonnable de le regrouper avec Postgres dans le conteneur de données :

# Utilisez la clé 'links' pour lier les conteneurs entre eux, c'est-à-dire utiliser le drapeau Docker --link.
links:
  - link:
      name: data
      alias: data
  - link:
      name: redis
      alias: redis

Le lien redis n’est pas nécessaire si vous combinez les conteneurs Redis et Postgres en un seul conteneur de données ; ceci est pour montrer ce que vous feriez.

Voici une copie des paramètres Postgres actuels dans env de samples/data.yml que vous devrez modifier en remplaçant SOME_SECRET :

  ## TODO : configurer la connectivité aux bases de données
  DISCOURSE_DB_SOCKET: ''
  #DISCOURSE_DB_USERNAME: discourse
  DISCOURSE_DB_PASSWORD: SOME_SECRET
  DISCOURSE_DB_HOST: data
  ## Si vous utilisez un seul conteneur data+redis, le suivant sera "data"
  DISCOURSE_REDIS_HOST: redis

Notez que pour un déploiement normal (pas multisite), vous n’aurez pas besoin de modifier d’autres lignes. DISCOURSE_DB_SOCKET est pour un socket de domaine Unix pour Postgres, ce n’est pas un numéro de port.

Voici un exemple de modification de la définition des volumes à la fin de web_only.yml que vous devrez utiliser si vous le copiez depuis app.yml au lieu de samples/web_only.yml :

@@ -75,10 +80,10 @@
 ## Le conteneur Docker est sans état ; toutes les données sont stockées dans /shared
 volumes:
   - volume:
-      host: /var/discourse/shared/standalone
+      host: /var/discourse/shared/web_only
       guest: /shared
   - volume:
-      host: /var/discourse/shared/standalone/log/var-log
+      host: /var/discourse/shared/web_only/log/var-log
       guest: /var/log

Maintenant, définissez le même mot de passe secret que vous avez utilisé dans containers/web_only.yml dans containers/data.yml à la place de SOME_SECRET.

Vous êtes maintenant prêt pour la migration.

C’est maintenant que vous prenez et téléchargez votre dernière sauvegarde avant d’essayer la migration rapide. Rappelez-vous, si quelque chose tourne mal ici, passez immédiatement à la méthode recommandée. Je ne saurais trop insister là-dessus.

Conteneurs de données (Postgres) et Redis séparés :

cd /var/discourse

./launcher stop app
cd  shared
mkdir data
mkdir redis
mv standalone/postgres_* data/
mv standalone/redis_data/ redis/
mv standalone web_only
mkdir -p data/log/var-log
mkdir -p redis/log/var-log

cd ..

./launcher destroy app

./launcher bootstrap data
./launcher bootstrap redis
./launcher start redis
./launcher start data

./launcher bootstrap web_only
./launcher start web_only

Conteneur de données combiné Postgres+Redis :

cd /var/discourse

./launcher stop app
cd  shared
mkdir data
mv standalone/postgres_* data/
mv standalone/redis_data/ data/
mv standalone web_only
mkdir -p data/log/var-log

cd ..

./launcher destroy app

./launcher bootstrap data
./launcher start data

./launcher bootstrap web_only
./launcher start web_only

Notez également que si vous avez précédemment configuré nginx externe, vous devrez modifier le chemin proxy_pass pour qu’il corresponde à l’emplacement du nouveau socket web_only ; par exemple, passer de http://unix:/var/discourse/shared/standalone/nginx.http.sock: à http://unix:/var/discourse/shared/web_only/nginx.http.sock:

Pour ma part, sur une VM à 2 cœurs avec 4 Go de RAM et un site avec des sauvegardes de 600 Mo sans téléchargements, ce processus a entraîné 12 minutes d’arrêt. Votre expérience peut varier.

Notez que rien de tout cela ne met à jour le launcher jusqu’à présent. Vous n’êtes peut-être pas à jour. (Par exemple, j’ai exécuté cela après que la mise à jour Postgres 12 ait été disponible, mais avant de l’avoir appliquée. Ce processus m’a laissé avec Postgres 10. Ensuite, la toute première chose que j’ai faite a été de reconstruire l’application de données, ce qui a mis à jour le launcher et m’a conduit avec succès au processus de mise à jour Postgres 12.)

Que faire lors des futures mises à jour

Après cette migration, si vous devez mettre à jour Redis ou les données, vous devez d’abord arrêter l’application web. Cela ressemblerait à ceci :

./launcher stop web_only
./launcher rebuild data # et/ou redis
./launcher rebuild web_only

Notez que si vous reconstruisez le conteneur data (ou postgres, ou redis), vous devrez créer un nouveau conteneur web pour le reconnecter au nouveau conteneur de données. Vous pouvez le faire soit en reconstruisant web_only, soit, si vous ne pensez pas avoir besoin de le reconstruire, un ./launcher destroy web_only; ./launcher start web_only fera l’affaire (et si vous obtenez une erreur concernant « conteneur de données manquant » ou similaire, c’est ce que vous devez faire).

Cependant, lorsque ni Postgres ni Redis n’ont besoin d’une mise à jour, il est beaucoup plus rapide de ne pas avoir à reconstruire ces conteneurs, et la plupart des reconstructions d’application sont simplement ./launcher rebuild web_only.

Alternativement, pour encore moins d’arrêt (rapporté à divers endroits entre 15 secondes et 2 minutes) :

./launcher bootstrap web_only
./launcher destroy web_only && ./launcher start web_only

Encore une fois, en passant à un déploiement multi-conteneurs, le suivi du moment où cela est approprié est maintenant votre travail. Vous recevrez des notifications dans la console d’administration concernant les mises à jour, mais elles ne s’appliqueront qu’au conteneur web_only. Rien ne vous dira quand vous devez mettre à jour Postgres ou Redis. Si vous faites cela, lisez la catégorie Annonces avant chaque mise à niveau de version que vous effectuez, et lisez les notes de version pour chaque nouvelle version vers laquelle ou à travers laquelle vous mettez à niveau. C’est-à-dire que si vous sautez une mise à jour de version, ne sautez pas la lecture des notes de version pour la version que vous avez sautée. (Envisagez de configurer une surveillance des notes de version, ou d’abonner votre lecteur de flux à https://meta.discourse.org/tag/release-notes.rss pour rester à jour.)

Notez que la reconstruction du conteneur web_only nécessite que la base de données soit en cours d’exécution, vous ne pouvez donc pas accélérer les choses en reconstruisant les deux ou trois conteneurs en parallèle. Si vous allez tous les reconstruire à chaque fois, restez avec le déploiement autonome standard recommandé ; ce sera plus rapide que de jongler avec plusieurs conteneurs.

Examen de la sauvegarde

Si vous sauvegardez les uploads séparément de la base de données, j’espère que vous avez un régime de sauvegarde distante basé sur les fichiers pour les uploads afin qu’ils soient sauvegardés pour une restauration en cas de catastrophe.

Examinez votre implémentation de sauvegarde distante pour vous assurer qu’elle sauvegardera les uploads dans /var/discourse/shared/web_only au lieu de /var/discourse/shared/standalone afin de maintenir vos sauvegardes à jour dans votre nouvelle implémentation multi-conteneurs.

22 « J'aime »

Salut, mcdanlj ! Je suis nouveau ici. Je constate que Discourse propose deux méthodes de déploiement : le mode autonome de app.yml, et votre méthode qui consiste à séparer la base de données et le cache Redis en mode multiconteneur web-only.yml, data.yml, redis.yml. Mais en même temps, je constate également que app.yml peut être connecté à Redis et à la base de données en modifiant les paramètres DISCOURSE_DB_HOST et DISCOURSE_REDIS_HOST. Alors pourquoi devons-nous diviser app.yml en web-only.yml, data.yml et redis.yml ?

Si vous avez déjà une base de données et redis (par exemple, rds et elasticache, ou créés par vous-même d’une autre manière), vous n’avez pas besoin d’avoir les vôtres.

Notez que chaque discourse a besoin de son propre redis.

1 « J'aime »

Merci Jay pour votre aimable explication ! Mais je suis toujours confus. D’après le Tutoriel de Falco, j’ai remarqué qu’il est facile d’utiliser RDS et Elasticache d’AWS sans avoir besoin de configurer web-only.yml, data.yml et redis.yml. Le Tutoriel de Falco ne modifie que les paramètres dans app.yml. Mais le Tutoriel de mcdanlj est différent. Est-ce parce que son forum est trop grand ? Par conséquent, il ne peut pas utiliser la méthode simple que Falco propose ?

Utiliser rds et exécuter son propre serveur de base de données sont deux choses différentes. Si vous avez beaucoup d’argent et d’expertise, rds est génial. Si vous ne savez rien, une installation dans un seul conteneur est incroyable. Si vous avez peu d’argent et souhaitez réduire les temps d’arrêt, l’approche à deux conteneurs est bonne.

La plupart du temps, vous devriez utiliser celle qui a le plus de sens pour vous.

1 « J'aime »

Merci beaucoup ! Peut-être qu’un seul conteneur est la meilleure solution pour moi :rofl: Je ne réalisais pas la différence entre RDS et mon propre serveur de base de données avant que vous ne me le disiez :joy:

1 « J'aime »

@ShawnLi Si le système à deux conteneurs vous semble compliqué, c’est un bon signe que le choix par défaut d’un seul conteneur est un bon choix pour vous. Le déploiement à deux conteneurs permet d’économiser quelques minutes d’indisponibilité environ une fois par mois lors des mises à jour, mais il nécessite une meilleure compréhension et vous oblige à suivre manuellement les détails des annonces à chaque nouvelle version.

C’est pourquoi j’ai commencé par :

:grinning:

2 « J'aime »

Merci mcdanlj ! Votre tutoriel est excellent et j’ai vraiment beaucoup appris grâce à lui. Je décide de choisir le réglage par défaut simple à un conteneur. Oui, je cours :rofl:

2 « J'aime »