J’ai fait fonctionner un forum Discourse avec une quantité substantielle de contenu et beaucoup d’images au cours des dernières années. Maker Forums possède plus de 100 Go d’images et plus de 400 000 messages, dont une part importante a été importée, principalement depuis Google+, et le reste a été créé sur le site. Ce message décrit les éléments de la manière dont j’ai finalement configuré Maker Forums et, plus tard, quelques autres instances Discourse. C’est ce que j’aurais aimé savoir en commençant, et que j’ai utilisé pour aider d’autres personnes à éviter certains des mêmes pièges pour leurs propres instances Discourse.
Il est temps de s’adresser à un public plus large.
Attention : Si vous n’êtes pas à l’aise pour travailler en tant qu’administrateur système Linux, ce guide ne vous est probablement pas destiné. Je ne suis peut-être même pas conscient de toutes les manières dont il suppose des connaissances sur Linux. Si cela vous semble éclairant à lire, vous êtes peut-être le public cible. Si cela vous semble confus à lire, vous n’êtes probablement pas le public cible. Si cela vous semble être du travail, veuillez envisager de payer CDCK ou @pfaffman pour faire fonctionner Discourse pour vous ; ils savent ce qu’ils font. Ou commencez par un site discourse.group gratuit, puis payez pour ce que vous devenez.
Comme si cela ne suffisait pas : j’ai plus d’expertise Linux que d’expertise Discourse. Mes avis sont donnés sans garantie. Si le fait d’essayer de suivre mes conseils provoque une panne de quoi que ce soit qui vous appartient (votre forum Discourse, votre système hôte ou votre cœur), vous gardez les deux morceaux, avec toutes les arêtes vives. Je ne prévois pas de fournir une quelconque forme de support pour le contenu de ce message.
Je prévois (mais ne promets pas) de maintenir ce document à jour avec mes pratiques concernant les instances Discourse que je participe à maintenir. Ceci est rédigé sous forme de conseils, mais je l’entends principalement comme des conseils pour moi-même et pour tous les administrateurs qui héritent de déploiements Discourse dont j’ai été responsable. Sinon, vous devriez le considérer comme un point de départ pour votre propre recherche afin de déterminer comment vous souhaitez déployer Discourse.
Configuration du système
Utilisez un système d’exploitation dérivé de CentOS ou Ubuntu LTS. Tout ce qui prend en charge Docker peut probablement fonctionner, mais j’ai utilisé ces deux-là.
Docker
Je suis un utilisateur de Fedora. J’étais le premier responsable du projet Fedora chez Red Hat, et je préférerais beaucoup faire fonctionner Discourse sur Podman parce que j’estime que son modèle de sécurité est préférable à celui de Docker. Cependant, les déploiements Discourse ne sont pris en charge que sur Docker, et vous serez assez pionnier si vous essayez de faire fonctionner autre chose. (Un jour, cela pourrait fonctionner avec Podman en utilisant podman-compose si docker-compose est un jour pris en charge.)
Maintenant que Docker prend en charge les cgroups v2, vous pouvez installer les versions officielles de Docker sur un système dérivé de CentOS :
dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
dnf install --allowerasing docker-ce docker-ce-cli
(Incluez --allowerasing en raison d’un conflit avec podman, runc et buildah qui peuvent déjà être installés ; ils doivent être supprimés pour installer docker.)
systemctl enable --now docker
J’ai testé cela avec AlmaLinux 9.
Sécurité
Cette section n’a vraiment rien à voir avec Discourse en soi, mais elle fait partie de ma pratique de sécurité normale. N’autorisez pas l’accès shell par mot de passe uniquement à aucun système sur le réseau, y compris une VM exécutant Discourse. Configurez l’accès SSH à l’aide d’une clé SSH chiffrée par une phrase de passe, et configurez le serveur ssh sur votre VM pour ne pas autoriser l’accès par mot de passe.
laptop$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/.../.ssh/id_rsa):
Enter passphrase (empty for no passphrase): SOME LONG PHRASE
Enter same passphrase again: SOME LONG PHRASE
Your identification has been saved in .ssh/id_rsa
Your public key has been saved in .ssh/id_rsa.pub
Les distributions Linux sont normalement configurées pour mémoriser la phrase de passe en mémoire, vous n’avez donc à la taper qu’une fois par démarrage. Windows n’est pas aussi pratique ; vous pourriez envisager d’utiliser Pageant avec PuTTY pour faire la même chose.
Tout d’abord, validez que le SSH entrant fonctionne sans mot de passe. Seulement après cela, sur le serveur, modifiez le fichier /etc/ssh/sshd_config et trouvez la ligne PasswordAuthentication. Définissez-la sur no pour désactiver l’accès par mot de passe entrant.
PasswordAuthentication no
Pare-feu
Vous devrez laisser les ports 80 et 443 généralement ouverts pour que letsencrypt puisse générer et renouveler vos certificats SSL, même avant que votre Discourse ne soit ouvert au public.
Si vous utilisez firewalld, ces commandes permettront de réaliser cela :
firewall-cmd --add-service http --add-service https --zone public
firewall-cmd --runtime-to-permanent
Appareil et système de fichiers séparés
Faites de /var/discourse/shared un appareil séparé avec son propre système de fichiers, avec 20 Go d’espace plus au moins le double de l’espace dont vous avez besoin pour les images ; ajoutez plus d’espace si vous allez utiliser prometheus. Si l’appareil sera facile à étendre plus tard (comme LVM ou tout stockage en bloc cloud comme le stockage en bloc élastique d’AWS), vous pouvez le surveiller et le développer selon vos besoins ; sinon, soyez généreux au départ. Si vous utilisez un appareil de stockage en bloc réseau, ne mettez pas de table de partition dessus. L’utiliser sans table de partition facilitera l’expansion ; vous n’aurez pas à modifier une table de partition. Dans de nombreux cas, vous pourrez l’étendre sans aucune interruption de système.
Sur Maker Forums, il s’agit d’un appareil de stockage en bloc réseau connecté à la VM sur laquelle Maker Forums fonctionne. Sur un autre forum Discourse, il s’agit d’un volume de stockage en bloc Digital Ocean. Chez Amazon, ce serait le stockage en bloc élastique AWS. Sur mon système de test exécutant une VM KVM sous libvirt sur Fedora, il s’agit d’un volume LVM sur l’hôte Fedora exporté vers la VM AlmaLinux en tant que disque virtuel. Dans chaque cas, je pouvais créer une nouvelle VM, copier les fichiers clés dessus, arrêter l’ancienne VM, connecter le volume /var/discourse/shared à la nouvelle VM, et être de nouveau opérationnel en quelques minutes. Cela rend les mises à niveau du système d’exploitation sur la VM relativement à faible risque.
Assurez-vous de commencer avec au moins 25 Go sur le système de fichiers racine de votre VM, sans inclure l’espace pour /var/discourse/shared. Cela sera utilisé pour tous les conteneurs docker, et le lanceur discourse échouera si moins de 5 Go sont libres à tout moment. Vous voulez également beaucoup d’espace disponible pour les mises à jour système. Si vous n’avez pas assez d’espace disque, c’est difficile à récupérer.
Dans la configuration du site, définissez force_https mais tenez compte des avertissements. Configurez-le en test, avant de rendre un site Discourse public. Notez que même avec force_https, vous avez besoin du port 80 ouvert, à la fois pour rediriger vers SSL sur le port 443 et pour renouveler votre certificat SSL letsencrypt. (Cependant, si vous utilisez cloudflare, utilisez sa fonctionnalité à la place ; il est rapporté qu’elle n’est pas compatible avec force_https dans Discourse.)
Configuration du noyau
Redis (l’un des composants clés sur lesquels Discourse est construit) recommande fortement de désactiver les pages transparentes géantes lors de l’utilisation de la persistance sur disque (ce que fait Discourse), et j’autorise également le sur-engagement de la mémoire.
echo 'sys.kernel.mm.transparent_hugepage.enabled=never' > /etc/sysctl.d/10-huge-pages.conf
echo 'vm.overcommit_memory=1' > /etc/sysctl.d/90-vm_overcommit_memory.conf
sysctl --system
Installation de Discourse
Bien que l’installation par défaut soit un conteneur unique, cela rend chaque mise à niveau, recommandée mensuellement, généralement une interruption de 10 à 15 minutes si elle est effectuée depuis la ligne de commande, ce qui est nécessaire pour certaines mises à jour, y compris celles qui mettent à jour les outils sur lesquels Discourse est construit, pour la sécurité ou de nouvelles fonctionnalités, ou lorsque la mise à jour en direct depuis l’interface utilisateur échoue pour une raison quelconque. Vous pouvez réduire cette interruption en pratique avec l’installation à deux conteneurs.
Installation à deux conteneurs
Commencez la configuration avec deux conteneurs.
./discourse-setup --two-container --skip-rebuild
${EDITOR:-nano} containers/data.yml
./launcher rebuild data
# ma préférence est d’utiliser app.yml mais vous pourriez rester avec web_only.yml, lisez le texte
mv containers/web_only.yml containers/app.yml
${EDITOR:-nano} containers/app.yml
./launcher rebuild app
Cela rend l’interruption système requise tous les quelques mois très courte, rarement perceptible ; de nombreux utilisateurs ne la remarqueront pas du tout s’ils ne cliquent pas ou ne font pas défiler le contenu pendant l’interruption. Cela facilite l’application de la plupart des mises à jour de sécurité ; c’est juste un petit problème plutôt qu’environ 15 minutes pour reconstruire tout. Le processus suivant fonctionne pour la plupart des mises à jour et donne généralement environ 30 à 90 secondes d’interruption, selon principalement les performances du système hôte et l’ensemble des plugins installés.
cd /var/discourse
git pull
./launcher bootstrap app
./launcher destroy app && ./launcher start app
./launcher cleanup
Ne retardez pas entre les invocations bootstrap et destroy/start. Rarement (peut-être une ou deux fois par an en pratique), les migrations de base de données effectuées vers la fin de la phase bootstrap provoqueront des erreurs plus ou moins sérieuses pour les utilisateurs de l’application, en raison du code plus ancien accédant à la base de données mise à jour.
Cela signifie bien que lorsque vous mettez à jour Discourse, vous devez également vérifier s’il faut mettre à jour le conteneur de données, mais cela est rarement requis (attendez généralement une ou deux fois par an). Selon le contenu de vos conteneurs de données et d’application et la vitesse du système, cela entraînera généralement une interruption entre 5 et 20 minutes.
cd /var/discourse
git pull
./launcher stop app
./launcher rebuild data
./launcher rebuild app
Pour en savoir plus sur le moment de mettre à jour le conteneur de données, voir :
(Dans mes propres déploiements, j’ai personnellement choisi d’appeler le conteneur web_only app à la fois parce que c’est plus facile à taper et parce que cela rend la plupart des instructions plus faciles à suivre. Ceci est non standard mais j’apprécie toujours la facilité d’utilisation. Cependant, c’était un travail supplémentaire, et cela fonctionne pour moi parce que je sais ce qui se passe. Si cela vous semble mauvais, restez avec le web_only par défaut pour un déploiement multi-conteneur.)
Notez qu’à un moment donné dans le futur, Docker pourrait vous obliger à effectuer une migration vers une nouvelle configuration pour connecter vos conteneurs :
Si vous avez 4 Go ou plus de mémoire, ou plusieurs CPU, lisez les conseils à :
Calendrier de mise à jour
Surveillez la balise release-notes (Cliquez sur release-notes et cliquez sur la cloche en haut à droite ; j’utilise « Watching First Post ») et/ou ajoutez https://meta.discourse.org/tag/release-notes.rss à votre flux RSS pour savoir quand il y a des versions. Lisez les notes de version avant de mettre à jour. S’il y a un changement de base de données, les notes de version le mentionneront. Elles signaleront également les versions contenant des mises à jour de sécurité. Lisez toutes les notes de version même si vous sautez la mise à jour vers une certaine version ; si vous ne lisez pas les notes de version pour une version qui met à jour la base de données, vous pourriez manquer les instructions de mise à jour de la base de données dans les notes de version que vous n’avez pas lues.
Courrier
Le courrier est toujours l’un des moyens clés pour maintenir les gens connectés. Configurez le courrier sortant et entrant pour que le courrier fonctionne pour vous. Si vous avez des problèmes, voir :
Continuez à faire des efforts
Maker Forums a vu des visiteurs occasionnels qui sont partis pour de longues périodes avant de revenir. Par défaut, Discourse cesse d’envoyer des e-mails récapitulatifs après un an. Envisagez de définir suppress_digest_email_after_days sur une valeur supérieure à la valeur par défaut de 365 jours si vous souhaitez encourager les visiteurs occasionnels à revenir lorsqu’ils voient quelque chose de nouveau et d’intéressant. Je l’ai rendu beaucoup plus long pour Maker Forums pour soutenir les visiteurs occasionnels qui restent à jour. Lire les e-mails récapitulatifs est un moyen valide de « traîner » sur un forum, et on ne sait jamais quand quelque chose va susciter l’intérêt de quelqu’un pour contribuer.
De même, par défaut, les utilisateurs non privilégiés qui n’ont pas beaucoup interagi (niveau de confiance 0 sans messages) sont finalement supprimés après 730 jours sans connexion. Définissez « clean up inactive users after days » sur 0 pour désactiver la suppression des utilisateurs, si vous voulez qu’ils puissent traîner en lisant des e-mails récapitulatifs indéfiniment.
Envisagez d’ajouter le plugin yearly review qui, une fois par an, générera un message comme 2020: The Year in Review et finira par l’envoyer par e-mail à vos utilisateurs inactifs ce qui pourrait les encourager à renouveler leur participation.
Conteneur de réception de courrier
Configurez un troisième conteneur en tant que récepteur de courrier. Il garantit le traitement des rebonds, rend votre traitement des rebonds indépendant du fournisseur de courrier sortant, et vous donne l’option de répondre par e-mail.
Assurez-vous que vous avez configuré SPF pour faire confiance à votre expéditeur de courrier ; au minimum, une politique comme v=spf1 +mx -all si vous envoyez et recevez via le même MX, mais plus spécifique peut être mieux considéré comme une protection contre les spams. Envisagez également DKIM.
Si vous utilisez le même nom d’hôte pour recevoir du courrier, vous devriez vraiment terminer SSL en dehors de votre conteneur comme pour une « page hors ligne » (voir ci-dessous) et devrez mapper vos certificats certbot dans le conteneur et redémarrer le conteneur après avoir exécuté certbot.
Terminer les connexions SSL utilisateur en dehors du conteneur
Il y a deux choix pour terminer SSL en dehors du conteneur, l’un ou l’autre apportant des avantages substantiels par rapport à la terminaison à l’intérieur du conteneur. Configurez-en un après avoir terminé avec succès discourse-setup et avoir bootstrappé votre forum.
Nginx externe
Utilisez nginx exécuté sur le système hôte, plutôt que seulement dans un conteneur, à la fois pour héberger une page de maintenance, et pour prendre en charge la journalisation des adresses IPv6 si votre hôte a un support IPv6. (Sinon, toutes les connexions IPv6 seront journalisées comme provenant d’une adresse RFC1918 interne associée à votre interface de réseau virtuel docker local.) Cette configuration présentera une page de maintenance temporaire pendant la plupart des opérations de maintenance qui redirigera éventuellement vers la page que l’utilisateur consultait.
Notez que les instructions sur cette page (actuellement) suggèrent d’installer un package appelé letsencrypt mais il s’appelle maintenant normalement certbot. Si vous suivez les instructions sur cette page pour utiliser --certonly, vous n’aurez pas besoin du plugin nginx pour certbot, mais l’installation du plugin nginx est un autre mécanisme. Sur les dérivés de CentOS, c’est :
dnf config-manager --set-enabled crb
dnf install epel-release
dnf install certbot python3-certbot-nginx
systemctl enable --now certbot-renew.timer
Assurez-vous que certbot redémarre nginx et le conteneur de réception de courrier pour que vous ne finissiez pas avec des navigateurs ou des e-mails bloquant le trafic avec votre site en raison de l’utilisation continue d’un ancien certificat expiré.
# systemctl edit certbot-renew
Pour un système sans récepteur de courrier, j’ai ajouté les deux lignes :
[Service]
ExecStartPost=/bin/systemctl reload nginx
Sur un système où j’utilise un conteneur de réception de courrier séparé qui partage également le certificat du système :
[Service]
ExecStartPost=/bin/systemctl reload nginx
ExecStartPost=/bin/sh -c 'cd /var/discourse && ./launcher restart mail-receiver'
Si vous utilisez SELinux, les conteneurs Ubuntu ne sont pas configurés pour étiqueter le fichier nginx.http.sock avec httpd_sys_content_t pour que nginx externe puisse y accéder. Vous avez deux choix.
Le premier est d’exécuter nginx en mode permissif, supprimant la protection SELinux pour lui : semanage permissive -a httpd_t
Cependant, cela supprime la protection SELinux de ce qui est probablement le service le plus pertinent ! Pour garder SELinux activé, vous devrez autoriser nginx à accéder aux pages d’erreur et passer du proxy via un socket de domaine unix à un port (ce qui est quelques µs plus lent, mais ne devrait pas être perceptible pour vos utilisateurs).
Tout d’abord, exécutez ces commandes pour autoriser nginx à accéder aux pages d’erreur :
semanage fcontext -a -t httpd_sys_content_t /var/www
restorecon -R -v /var/www
Ensuite, dans votre app.yaml, commentez ou supprimez - "templates/web.socketed.template.yml", exposez le port 80 comme un port différent sur la machine locale et reconstruisez le conteneur.
expose:
- "8008:80" # http
N’utilisez pas https ici — vous avez terminé SSL dans le nginx externe, et l’en-tête X-Forwarded-Proto indique à Discourse que la demande est arrivée via https. Assurez-vous que le port 8008 (ou tout autre port que vous avez choisi) n’est pas exposé publiquement par vos paramètres de pare-feu.
Ensuite, exécutez cette commande pour autoriser nginx à se connecter via le réseau au conteneur :
setsebool -P httpd_can_network_connect 1
Ensuite, modifiez votre configuration nginx externe du proxy via nginx.http.sock vers http://127.0.0.1:8008 (ou votre port choisi) et effacez l’en-tête Connection: close par défaut, afin que le nginx externe n’ait pas à établir une nouvelle connexion IP pour chaque demande.
...
location / {
proxy_pass http://127.0.0.1:8008;
proxy_set_header Host $http_host;
proxy_http_version 1.1;
# Disable default "Connection: close"
proxy_set_header "Connection" "";
...
La suppression de web.socketed.template.yml a également supprimé l’invocation real_ip, donc ajoutez-la à nouveau. Assurez-vous que la plage d’adresses IP que vous utilisez a du sens ; la valeur par défaut de Docker est d’utiliser l’espace d’adressage RFC1918 172.16* qui ne sont pas acheminés sur Internet public par politique. Ajoutez à votre fichier app.yml quelque chose comme ceci dans la section run, en sélectionnant un ou plusieurs des espaces d’adressage RFC1918 ou tout autre chose approprié pour votre déploiement :
run:
- file:
path: /etc/nginx/conf.d/outlets/server/real-ip-recursive.conf
chmod: 644
contents: |
real_ip_recursive on;
- file:
path: /etc/nginx/conf.d/outlets/server/real-ip-header.conf
chmod: 644
contents: |
real_ip_header X-Forwarded-For;
- file:
path: /etc/nginx/conf.d/outlets/server/set-real-ip-from.conf
chmod: 644
contents: |
set_real_ip_from 192.168.0.0/16;
set_real_ip_from 172.16.0.0/12;
set_real_ip_from 10.0.0.0/8;
Ceci est requis pour que la limitation de débit fonctionne correctement, ainsi que pour attribuer les adresses IP d’inscription et de dernière utilisation pour les utilisateurs.
Pour plus d’informations :
Service externe
Je n’ai pas configuré Fastly ou Cloudflare devant Discourse, mais d’autres l’ont fait, et contrairement à nginx externe exécuté sur l’hôte, ils peuvent vous permettre de servir une page de maintenance tandis que le système hôte est complètement hors service, comme lors d’un redémarrage pendant une mise à jour système sur votre hôte. Si cela en vaut la peine pour vous, voici comment faire :
Ne vous précipitez pas vers les téléchargements S3
n
Soyez très sûr que vous voulez toujours utiliser S3 (ou équivalent) pour les images téléchargées avant d’activer enable_s3_uploads pendant la configuration, ou de migrer vers celui-ci plus tard. Soyez conscient que l’utilisation de S3 (s3_endpoint) avec son CDN associé (s3_cdn_url) pour les images entraînera également le service javascript via ce CDN. La migration de S3 vers le stockage local n’est pas prise en charge et il n’y a pas de plans concrets pour l’implémenter à ce stade. C’est une « porte à sens unique » qui ne peut même pas être annulée par une sauvegarde et une restauration complètes. Si vous utilisez S3 ou similaire, n’utilisez pas Digital Ocean Spaces à la place de S3. Il y a des références ici sur meta à ce qu’il n’est pas fiable.
J’ai déplacé mon site pour servir des images via Digital Ocean Spaces et son CDN associé au début, et j’ai dû écrire des centaines de lignes de code personnalisé pour migrer vers le stockage local, causant des dommages mineurs à mon instance Discourse dans le processus, en raison de la « porte à sens unique » n’étant pas bien comprise.
Pour plus d’informations :
Vous n’avez pas besoin d’activer les téléchargements S3 pour utiliser un CDN pour votre Discourse. Envisagez d’utiliser un CDN indépendant (par exemple Cloudflare, CloudFront, Fastly, GCS CDN) devant un Discourse qui gère ses propres images. C’est ma compréhension indirecte que l’avertissement selon lequel Cloudflare n’est pas recommandé est dû au fait que « Rocket Loader » modifie JavaScript ; et qu’à ce stade, tant que vous n’utilisez pas « Rocket Loader », il fonctionne correctement.
Paramètres Discourse pour la modération
n
Sur tout site où la modération est active, envisagez fortement la configuration enable_whispers qui permet aux modérateurs et aux administrateurs de discuter d’un sujet en ligne. De plus, les modérateurs de catégorie ont reçu plus de capacités dans les versions récentes de Discourse. Il vaut la peine de connaître enable_category_group_moderation si vous avez des experts dans différents sujets avec leurs propres catégories, ou si vous avez des catégories fonctionnellement séparées comme pour le support.
La géolocalisation peut être utile pour essayer de comprendre si un compte est légitime.
La fonctionnalité Discourse Templates est vraiment utile pour les modérateurs. Elle vous permet de collaborer sur des réponses communes. Nous en avons quelques dizaines à Maker Forums. Elle a plus de fonctionnalités que le plugin « Canned Responses » précédent qu’elle remplace.
La fonctionnalité User Notes aidera les modérateurs à partager des notes sur les utilisateurs. Vous pouvez les utiliser pour des choses comme :
- « Gardez un œil sur cet utilisateur, il peut être malveillant parce que … »
- « Bien que ce comportement semble suspect, j’ai validé que c’est un utilisateur légitime par … »
- « J’ai déjà une conversation avec cet utilisateur pour aborder les préoccupations, les autres modérateurs n’ont pas besoin de s’ajouter. »
Accessibilité de l’information
n
Le plugin Discourse Solved marque non seulement les problèmes résolus pour que les visiteurs du site puissent les identifier plus facilement, mais je comprends qu’il pourrait également prioriser les résultats de recherche Google.
Les informations publiques sont plus accessibles que les informations privées. Sur Maker Forums, notre FAQ décourage fortement les messages personnels et rappelle à tous que les messages personnels ne sont pas vraiment privés. Cependant, par défaut, les utilisateurs peuvent voir le message :
Vous avez répondu à user 3 fois, saviez-vous que vous pouviez leur envoyer un message personnel à la place ?
Si vous voulez vraiment encourager les utilisateurs à passer aux messages personnels, je vous suggère d’aller dans Admin → Customize → Text et de modifier le modèle get_a_room pour corriger la virgule.
Si, comme Maker Forums, vous voulez garder la conversation en public pour bénéficier à tout le monde, Admin → Settings → Other → get_a_room_threshold peut être défini plus haut, comme 1000000.
De même, si vous avez un forum fournissant de l’aide, la valeur par défaut de max_replies_in_first_day 10 pourrait pousser les nouveaux utilisateurs dans une conversation demandant de l’aide vers des messages personnels lorsqu’ils utilisent leur budget de réponses. Envisagez d’augmenter ce paramètre pour éviter de pousser les conversations vers des messages personnels.
Connecter les utilisateurs, construire une communauté
n
Quelques plugins peuvent aider à connecter les utilisateurs entre eux.
Si votre forum n’a pas trop d’utilisateurs simultanés, envisagez le plugin Who’s Online pour donner aux gens un plus grand sentiment de connexion. Vous pourriez vouloir limiter l’affichage aux utilisateurs connectés, peut-être seulement ceux qui ont atteint au moins le niveau de confiance 1. Vous pouvez l’utiliser uniquement pour ajouter un indicateur de présence (whos_online_avatar_indicator) aux avatars en définissant whose_online_minimum_display très haut et whos_online_hide_below_minimum_display à true. Cela peut être utile pour les forums de support pour soutenir et encourager des questions et réponses rapides tout en aidant les utilisateurs à résoudre des problèmes.
Cependant, un sentiment de présence peut avoir deux aspects. Un utilisateur qui est en ligne à un moment différent de la majorité des utilisateurs du forum pourrait se sentir seul, ou le forum pourrait sembler une « ville fantôme » pour eux.
Si vous avez des utilisateurs dans de nombreux pays et voulez qu’ils aient des indices sur quand ils sont plus susceptibles d’être disponibles, envisagez le plugin National Flags, et encouragez les utilisateurs à définir un drapeau national dans leur profil.
Un délicat est la traduction. Il serait pratique d’aider les gens à communiquer quand ils ne parlent pas la même langue, mais actuellement (au moment de l’écriture) il n’y a pas de services de traduction avec des niveaux de service gratuits. Si vous choisissez de payer pour des services de traduction, vous pouvez activer la traduction avec le plugin Discourse Translator.
Sauvegarde
n
Pour les fichiers système, envisagez de sauvegarder au moins :
/var/discourse/containers(pour les détails de configuration de discourse)/var/www(pour les pages d’erreur)/etc/ssl(pour la configuration letsencrypt, pour éviter de devoir bootstrapper certbot dans le cadre de la restauration d’une sauvegarde ; sinon vous devez commenter la partie SSL de votre configuration nginx pendant que vous bootstrappez ; cela ne fonctionne que si vous gardez les sauvegardes récentes car les certificats ont une courte validité)/etc/systemd/system/backup-uploads.service(pour faire des sauvegardes d’images vers S3)/usr/local/bin/mc(minio-client en tant qu’outil de sauvegarde d’images, si vous choisissez de l’utiliser)/root/.mc(configuration pour la sauvegarde d’images avec minio-client)/root/.ssh(authentification des sessions SSH entrantes)
Certains de ces fichiers vous pouvez les sauvegarder en les commitant dans Git et en les poussant quelque part hors site. Si les fichiers que vous commitez dans Git incluent des secrets (comme les mots de passe de base de données), ne les poussez définitivement pas vers un référentiel public. Alternativement, vous pourriez scripter la copie hors du système et les commiter dans Git sur un système de supervision que vous contrôlez. Scriptez cela suffisamment fréquemment pour garder vos sauvegardes de /etc/ssl fraîches.
L’objectif est d’avoir des sauvegardes en cas de catastrophe et d’avoir un enregistrement des changements en cas d’erreur.
Une meilleure alternative pour la plupart de ces fichiers est de garder les copies canoniques ailleurs, et d’utiliser un outil comme Ansible pour maintenir la configuration sur le système, ce qui rend aussi facile de mettre à jour après une sauvegarde. Mais si vous allez faire cela, vous l’avez probablement compris sans que je vous le dise !
Configuration Discourse pour la sauvegarde
n
-
Sauvegardez les miniatures avec
include_thumbnails_in_backups. Une restauration sans miniatures prend beaucoup de temps pour les régénérer. Si votre site n’a pas beaucoup de graphiques, les miniatures prennent un espace insignifiant. Si votre site est riche en graphiques, la régénération des miniatures pourrait prendre des jours. Pendant que les miniatures sont régénérées, les notifications par e-mail seront désactivées. Dans les deux cas, il n’y a aucun sens à omettre les miniatures des sauvegardes. -
N’incluez pas les images dans les sauvegardes si vous avez beaucoup d’images. Cela rendra les sauvegardes lentes et encombrantes. Sauvegardez-les séparément. Si vous sauvegardez les images après votre sauvegarde de base de données, vos sauvegardes seront cohérentes.
-
Prévoyez que les sauvegardes partent hors site d’une manière ou d’une autre.
Cette page montre comment configurer les sauvegardes de base de données vers S3 ou quelque chose comme S3 :
Sauvegarder avec restic
n
Configurez discourse pour sauvegarder vers le système de fichiers, puis sauvegardez depuis le système de fichiers vers une cible de sauvegarde distante avec restic. Voici un exemple de recette.
# dnf install restic
# mkdir /var/restic
# mkdir /opt/backup
# cd /opt/backup
# cat > backup <<EOF
#!/usr/bin/bash
set -e
. /opt/backup/backup-config
restic --cache-dir=/var/restic \
backup \
/etc \
/root \
/var/discourse \
/opt/backup \
--exclude /var/discourse/shared/data/postgres_data
restic --cache-dir=/var/restic forget \
--prune --keep-hourly 24 --keep-daily 7 --keep-monthly 3
EOF
# chmod +x backup
Ces détails varieront selon la cible restic. Toutes n’utilisent pas les variables d’environnement AWS, alors lisez la documentation de restic.
# cat > backup-config <<EOF
### Ces détails dépendent de la cible restic que vous configurez, alors modifiez-les
export AWS_ACCESS_KEY_ID=votre-clef-ici
export AWS_SECRET_ACCESS_KEY=identique
export RESTIC_PASSWORD_FILE=/root/restic-password
export RESTIC_REPOSITORY=voir-la-documentation-restic
EOF
# {$EDITOR:-nano} /root/restic-password
Vous devrez conserver une copie de ce que vous avez mis dans /root/restic-password, sinon vous ne pourrez pas lire les sauvegardes ! Utilisez votre coffre-fort de mots de passe.
Enfin, créez quelques services, initialisez le dépôt restic et réglez une minuterie pour que les sauvegardes démarrent.
# cat > /etc/systemd/system/backup.service <<EOF
[Unit]
Description=Back up to remote target
Wants=network-online.target
After=network-online.target
[Service]
Type=oneshot
StandardOutput=file:/var/log/backup.out
StandardError=file:/var/log/backup.err
WorkingDirectory=/var/discourse
ExecStart=/opt/backup/backup
[Install]
WantedBy=multi-user.target
EOF
# cat > /etc/systemd/system/backup.timer <<EOF
[Unit]
Description=Regular system backups
[Timer]
Persistent=true
OnCalendar=00/4:30:00
Unit=backup.service
[Install]
WantedBy=timers.target
EOF
# systemctl daemon-reload
# . /opt/backup/backup-config
# restic init
# /opt/backup/backup
# systemctl enable backup.timer
Après ce processus, vous devriez pouvoir constater que vous avez créé votre sauvegarde initiale.
# restic snapshots
J’ai utilisé avec succès des sauvegardes restic effectuées de cette manière pour déplacer un serveur Discourse d’un système à un autre en utilisant la commande restic restore.
Sauvegardes d’images minio en streaming
En alternative à Restic, bien que les sauvegardes de base de données puissent être stockées sur S3, il n’y a pas de sauvegarde d’images S3 distincte du service d’images depuis S3. Une alternative consiste à utiliser minio-client pour copier les images vers n’importe quel stockage semblable à S3. Cela peut concerner de nombreuses cibles semblables à S3, y compris S3 et minio, mais pas DigitalOcean Spaces car il est construit sur le système de fichiers Ceph qui n’implémente pas l’API ListObjectsV2 de la même manière que S3.
Dans S3, créez un bucket qui bloque l’accès public (Permissions → Block public access est le moyen le plus simple de faire cela correctement dans AWS).
Installez minio-client (mc) d’une manière ou d’une autre. Voici une méthode.
curl https://dl.min.io/client/mc/release/linux-amd64/mc > /usr/local/bin/mc && chmod +x /usr/local/bin/mc
Configurez minio-client avec un alias appelé backup en utilisant une commande semblable à celle-ci :
# mc alias set backup https://s3.amazonaws.com ACCESSKEY SECRETKEY --api S3v4
# mc mirror /var/discourse/shared/standalone/uploads backup/UPLOADS-BACKUP-BUCKET
Ensuite, créez un service /etc/systemd/system/backup-uploads.service comme suit
[Unit]
Description=Neartime remote backup sync of discourse uploads
After=network.target
StartLimitIntervalSec=0
[Service]
Type=simple
Restart=always
RestartSec=600
User=root
ExecStart=/usr/local/bin/mc mirror --overwrite -a --watch /var/discourse/shared/app/uploads backup/UPLOADS-BACKUP-BUCKET
[Install]
WantedBy=multi-user.target
Notez que UPLOADS-BACKUP-BUCKET ici doit être un bucket différent du s3_backup_bucket dans lequel vous configurez Discourse pour télécharger les sauvegardes de base de données. Notez également que le chemin sera /var/discourse/shared/web_only/uploads si vous utilisez le déploiement multi-conteneurs standard.
# systemctl enable backup-uploads
# systemctl start backup-uploads
# journalctl -fu backup-uploads
Téléchargez une image de test et assurez-vous de voir des lignes indiquant une sauvegarde réussie des images originales et optimisées. Control-C quittera le mode suivi dans journalctl.
Récupération
Je n’ai jamais eu à tester ce plan à ce jour. Ce résumé pourrait manquer quelque chose.
- Restaurez tous les fichiers sauvegardés en général
- Démarrez nginx (votre page de maintenance s’affichera maintenant)
- Effectuez un déploiement normal de Discourse en utilisant les fichiers restaurés dans /var/discourse/containers
- Installez minio-client dans /usr/local/bin/mc si vous ne l’avez pas restauré depuis les sauvegardes
- Si vous n’avez pas sauvegardé
/root/mc, configurez l’alias de sauvegarde# mc alias set backup https://s3.amazonaws.com ACCESSKEY SECRETKEY --api S3v4 # mc cp backup/UPLOADS-BACKUP-BUCKET /var/discourse/shared/app/uploads- Restaurez la sauvegarde de base de données la plus récente ; je vous recommande de Restore a backup from the command line
- Uniquement après avoir confirmé que le site est opérationnel, reconfigurez la sauvegarde des uploads vers S3 comme documenté ci-dessus.
Sauvegardes postgresql en streaming
À l’avenir, je pourrai créer, tester et fournir une configuration pour permettre l’utilisation de l’archivage WAL continu pour streamer des sauvegardes Postgres quasi-instantanées avec minio-client en utilisant la commande archive-command dans postgresql, semblable au streaming des sauvegardes d’uploads.
Surveillance des performances
Il existe au moins deux approches pour la surveillance des performances.
Conteneur Prometheus
Configurez prometheus, en plaçant les journaux prometheus dans /var/discourse/shared/prometheus si vous l’exécutez sur le même système. Les fichiers Prometheus peuvent devenir volumineux, et vous ne voulez pas qu’ils remplissent le système de fichiers racine ; vous voudrez probablement également les emporter si vous passez à un système hôte plus récent (soit en passant à une VM plus grande, soit à une VM avec une installation de système d’exploitation plus récente).
Si vous déployez prometheus sur le système Discourse (ou ailleurs sur Internet public), configurez la sécurité devant lui. Installé de cette manière, une option serait une configuration nginx comme suit :
location /prometheus/ {
auth_basic "Prometheus";
auth_basic_user_file /etc/nginx/prometheus-htpasswd;
proxy_pass http://localhost:9090/;
}
Sysstat
Si Prometheus est trop complexe, envisagez d’utiliser sysstat à la place.
dnf install sysstat(ouapt install sysstatsur debian et dérivés)systemctl enable --now sysstatsystemctl enable --now sysstat-collect.timersystemctl enable --now sysstat-summary.timersystemctl edit sysstat-collect.timeret changezOnCalendar=*:00/10enOnCalendar=*:00/2- Si /etc/default/sysstat existe, changez
falseentrue
Après cela, la commande sar peut vous indiquer si vous manquez de ressources de temps en temps.
Autres ressources
Voici une discussion complémentaire (et plus concise) sur l’utilisation de Discourse en interne comme forme principale de communication interne.