Ich betrete seit einigen Jahren ein Discourse-Forum mit einer beträchtlichen Menge an Inhalten und zahlreichen Bildern. Maker Forums verfügt über mehr als 100 GB an Bildern und über 400.000 Beiträge, von denen ein beträchtlicher Teil importiert wurde, hauptsächlich von Google+, und der Rest auf der Seite erstellt wurde. Dieser Beitrag beschreibt Elemente davon, wie ich Maker Forums und später einige andere Discourse-Instanzen schließlich konfiguriert habe. Das ist es, was ich gewusst hätte, als ich angefangen habe, und was ich verwendet habe, um anderen zu helfen, einige der gleichen Fallstricke für ihre eigenen Discourse-Instanzen zu vermeiden.
Zeit für ein breiteres Publikum.
Warnung: Wenn du dich nicht wohlfühlst, als Linux-Systemadministrator zu arbeiten, ist dieser Leitfaden wahrscheinlich nicht für dich. Ich bin mir vielleicht nicht einmal aller Möglichkeiten bewusst, in denen er Kenntnisse über Linux voraussetzt. Wenn das Lesen dieses Textes erhellend wirkt, könntest du die Zielgruppe sein. Wenn das Lesen dieses Textes verwirrend wirkt, bist du wahrscheinlich nicht die Zielgruppe. Wenn das wie Arbeit klingt, erwäge bitte, CDCK oder @pfaffman zu bezahlen, um Discourse für dich zu betreiben; sie wissen, was sie tun. Oder beginne mit einer kostenlosen discourse.group-Site und zahle dann für das, worin du dich entwickelst.
Als ob das nicht genug wäre: Ich habe mehr Linux-Expertise als Discourse-Expertise. Meine Meinungen kommen ohne Garantie. Wenn das Befolgen meiner Ratschläge dazu führt, dass irgendetwas von dir kaputt geht (dein Discourse-Forum, dein Host-System oder dein Herz), behältst du beide Teile, mit allen scharfen Kanten. Ich plane nicht, irgendeine Form von Support für den Inhalt in diesem Beitrag zu bieten.
Ich plane (verspreche aber nicht), dieses Dokument mit meinen Praktiken auf dem neuesten Stand zu halten, die die Discourse-Instanzen abdecken, an deren Wartung ich mich beteilige. Dies ist in Form von Ratschlägen geschrieben, aber ich beabsichtige es primär als Rat an mich selbst und an alle Administratoren, die Discourse-Deployments übernehmen, für die ich verantwortlich war. Andernfalls solltest du es als einen Ausgangspunkt für deine eigene Recherche betrachten, um zu bestimmen, wie du Discourse bereitstellen möchtest.
Systemsetup
Verwende ein CentOS-abgeleitetes oder Ubuntu LTS-Betriebssystem. Alles, was Docker unterstützt, kann wahrscheinlich zum Laufen gebracht werden, aber ich habe diese beiden verwendet.
Docker
Ich bin ein Fedora-Nutzer. Ich war der erste Fedora Project Lead bei Red Hat, und ich würde Discourse viel lieber auf Podman ausführen, da ich der Meinung bin, dass sein Sicherheitsmodell dem von Docker überlegen ist. Discourse-Deployments werden jedoch nur auf Docker unterstützt, und du wirst ein ziemlicher Pionier sein, wenn du versuchst, auf etwas anderem zu laufen. (Es könnte eines Tages mit Podman unter Verwendung von podman-compose funktionieren, wenn docker-compose jemals unterstützt wird.)
Da Docker jetzt cgroups v2 unterstützt, kannst du die offiziellen Docker-Builds auf einem CentOS-abgeleiteten System installieren:
dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
dnf install --allowerasing docker-ce docker-ce-cli
(Inkludiere --alloweraseing wegen eines Konflikts mit podman, runc und buildah, die möglicherweise bereits installiert sind; sie müssen gelöscht werden, um docker zu installieren.)
systemctl enable --now docker
Ich habe dies mit AlmaLinux 9 getestet.
Sicherheit
Dieser Abschnitt hat eigentlich nichts mit Discourse per se zu tun, aber es ist Teil meiner normalen Sicherheitspraxis. Erlaube keinen Shell-Zugriff nur mit Passwort auf irgendein System im Netzwerk, einschließlich einer VM, die Discourse ausführt. Richte SSH-basierten Zugriff mit einem passphrasen-verschlüsselten SSH-Schlüssel ein und konfiguriere den SSH-Server auf deiner VM so, dass kein Passwortzugriff erlaubt ist.
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
Linux-Distributionen sind normalerweise so eingerichtet, dass sie die Passphrase im Speicher merken, sodass du sie nur einmal pro Bootvorgang eingeben musst. Windows ist nicht so bequem; du könntest erwägen, Pageant mit PuTTY zu verwenden, um dasselbe zu tun.
Überprüfe zuerst, ob eingehende SSH-Verbindungen ohne Passwort funktionieren. Erst danach, auf dem Server, modifiziere die Datei /etc/ssh/sshd_config und finde die PasswordAuthentication-Zeile. Setze sie auf no, um den eingehenden Passwortzugriff zu deaktivieren.
PasswordAuthentication no
Firewall
Du musst die Ports 80 und 443 allgemein offen lassen, damit letsencrypt deine SSL-Zertifikate generieren und erneuern kann, noch bevor dein Discourse für die Öffentlichkeit zugänglich ist.
Wenn du firewalld verwendest, werden diese Befehle dies erreichen:
firewall-cmd --add-service http --add-service https --zone public
firewall-cmd --runtime-to-permanent
Separates Gerät und Dateisystem
Mache /var/discourse/shared zu einem separaten Gerät mit seinem eigenen Dateisystem, mit 20 GB Speicherplatz plus mindestens doppelt so viel Raum, wie du für Bilder brauchst; füge mehr Speicherplatz hinzu, wenn du prometheus verwenden wirst. Wenn das Gerät später leicht erweiterbar sein wird (wie LVM oder irgendein Cloud-Block-Speicher wie AWS Elastic Block Storage), kannst du es überwachen und nach Bedarf vergrößern; anderenfalls sei zu Beginn großzügig. Wenn du ein Netzwerk-Speicherblockgerät verwendest, lege keine Partitionstabelle darauf. Die Verwendung ohne Partitionstabelle macht es einfacher zu erweitern; du musst keine Partitionstabelle modifizieren. In vielen Fällen wirst du in der Lage sein, ohne Systemausfallzeiten zu erweitern.
Auf Maker Forums ist dies ein Netzwerk-Speicherblockgerät, das an die VM angehängt ist, auf der Maker Forums läuft. Auf einem anderen Discourse-Forum ist es ein Digital Ocean Block Storage Volume. Bei Amazon wäre dies AWS Elastic Block Storage. Auf meinem Testsystem, das eine KVM-VM unter libvirt auf Fedora ausführt, ist es ein LVM-Volume auf dem Fedora-Host, das als virtuelle Festplatte an die AlmaLinux-VM exportiert wird. In jedem Fall konnte ich eine neue VM erstellen, wichtige Dateien darauf kopieren, die alte VM stoppen, das /var/discourse/shared-Volume an die neue VM anhängen und innerhalb von Minuten wieder online gehen. Dies macht Betriebssystem-Upgrade auf der VM relativ risikoarm.
Stelle sicher, dass du mit mindestens 25 GB auf dem Root-Dateisystem für deine VM beginnst, ohne jeglichen Speicherplatz für /var/discourse/shared. Dies wird für alle Docker-Container verwendet, und der Discourse-Launcher wird fehlschlagen, wenn weniger als 5 GB frei sind. Du möchtest auch viel Speicherplatz für Systemupdates verfügbar haben. Wenn du nicht genug Festplattenspeicher hast, ist dies schwer zu beheben.
In der Site-Konfiguration, setze force_https, aber beachte die Warnungen. Richte es im Test ein, bevor du eine Discourse-Site öffentlich machst. Beachte, dass du auch mit force_https Port 80 offen haben musst, sowohl um zu SSL auf Port 443 umzuleiten als auch um dein letsencrypt-SSL-Zertifikat zu erneuern. (Wenn du jedoch Cloudflare verwendest, verwende dessen Funktion stattdessen; es wird berichtet, dass es nicht mit force_https in Discourse kompatibel ist.)
Kernelkonfiguration
Redis (eine der Schlüsselkomponenten, auf denen Discourse aufgebaut ist) empfiehlt dringend, transparente Huge Pages zu deaktivieren, wenn On-Disk-Persistenz verwendet wird (was Discourse tut), und ich erlaube auch Memory-Overcommit.
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
Discourse-Installation
Während die Standardinstallation ein einzelner Container ist, macht dies jedes Upgrade, empfohlen monatlich, typischerweise zu einer 10-15-minütigen Ausfallzeit, wenn es von der Befehlszeile aus durchgeführt wird, was für einige Updates notwendig ist, einschließlich solcher, die die Tools aktualisieren, auf denen Discourse aufgebaut ist, aus Sicherheitsgründen oder für neue Funktionen, oder wenn das Live-Update über die UI aus irgendeinem Grund fehlschlägt. Du kannst diese Ausfallzeit in der Praxis mit der Zwei-Container-Installation reduzieren.
Zwei-Container-Installation
Beginne die Konfiguration mit zwei Containern.
./discourse-setup --two-container --skip-rebuild
${EDITOR:-nano} containers/data.yml
./launcher rebuild data
# meine Präferenz ist es, app.yml zu verwenden, aber du könntest bei web_only.yml bleiben, lies den Text
mv containers/web_only.yml containers/app.yml
${EDITOR:-nano} containers/app.yml
./launcher rebuild app
Dies macht die erforderliche Systemausfallzeit alle paar Monate sehr kurz, selten bemerkbar; viele Nutzer werden es überhaupt nicht bemerken, wenn sie während der Ausfallzeit nicht klicken oder durch den Inhalt scrollen. Dies macht es einfacher, die meisten Sicherheitsupdates anzuwenden; es ist nur ein kleiner Störung statt etwa 15 Minuten, in denen alles neu gebaut wird. Der folgende Prozess funktioniert für die meisten Updates und gibt typischerweise etwa 30-90 Sekunden Ausfallzeit, abhängig hauptsächlich von der Leistung des Host-Systems und der installierten Plugins.
cd /var/discourse
git pull
./launcher bootstrap app
./launcher destroy app && ./launcher start app
./launcher cleanup
Verzichte nicht zwischen den Bootstrap- und Destroy/Start-Aufrufen. Selten (vielleicht ein- oder zweimal pro Jahr in der Praxis) werden die Datenbankmigrationen, die gegen Ende der Bootstrap-Phase durchgeführt werden, mehr oder weniger schwerwiegende Fehler bei den Nutzern der App verursachen, aufgrund des älteren Codes, der auf die aktualisierte Datenbank zugreift.
Dies bedeutet, dass du, wenn du Discourse aktualisierst, auch prüfen musst, ob du den Data-Container ebenfalls aktualisieren musst, aber dies ist selten erforderlich (typischerweise erwarte ich ein- oder zweimal pro Jahr). Abhängig vom Inhalt deiner Data- und App-Container und der Geschwindigkeit des Systems wird dies typischerweise zu einer Ausfallzeit zwischen 5 und 20 Minuten führen.
cd /var/discourse
git pull
./launcher stop app
./launcher rebuild data
./launcher rebuild app
Für mehr darüber, wann du den Data-Container aktualisieren sollst, siehe:
(In meinen eigenen Deployments habe ich persönlich beschlossen, den web_only-Container app zu nennen, sowohl weil es einfacher zu tippen ist als auch weil es die meisten Anweisungen einfacher zu folgen macht. Dies ist nicht standard, aber ich schätze die Benutzerfreundlichkeit immer wieder. Es war jedoch zusätzliche Arbeit, und es funktioniert für mich, weil ich weiß, was vor sich geht. Wenn das für dich schlecht klingt, bleibe bei der Standard-web_only für ein Multi-Container-Deployment.)
Beachte, dass Docker zu einem bestimmten Zeitpunkt in der Zukunft dich möglicherweise dazu zwingt, eine Migration zu einer neuen Konfiguration für die Verbindung deiner Container durchzuführen:
Wenn du 4 GB oder mehr Speicher oder mehrere CPUs hast, lies die Ratschläge unter:
Update-Zeitplan
Beobachte das #release-notes-Tag (Klicke auf release-notes und klicke auf die Glocke oben rechts; ich verwende „First Post watching“) und/oder füge https://meta.discourse.org/tag/release-notes.rss zu deinem RSS-Feed hinzu, um zu wissen, wann es Releases gibt. Lies die Release-Notes, bevor du aktualisierst. Wenn es eine Datenbankänderung gibt, werden die Release-Notes dies erwähnen. Sie werden auch Releases hervorheben, die Sicherheitsupdates enthalten. Lies alle Release-Notes, auch wenn du tatsächlich auf einige Versionen verzichtest; wenn du die Release-Notes für ein Release nicht liest, das die Datenbank aktualisiert, könntest du Datenbank-Update-Anweisungen in den Release-Notes übersehen, die du nicht gelesen hast.
Mail ist immer noch einer der Schlüsselwege, um Menschen in Kontakt zu halten. Richte ausgehende und eingehende Mail ein, um Mail für dich arbeiten zu lassen. Wenn du Probleme hast, siehe:
Bleibe in Kontakt
Maker Forums hat gelegentliche Besucher gesehen, die für lange Zeiträume weg waren, bevor sie zurückkehrten. Standardmäßig stoppt Discourse das Senden von Digest-E-Mails nach einem Jahr. Erwäge, suppress_digest_email_after_days auf etwas länger als die Standard-365 Tage zu setzen, wenn du gelegentliche Besucher ermutigen möchtest, zurückzukehren, wenn sie etwas Neues und Interessantes sehen. Ich habe es für Maker Forums substantially länger gemacht, um gelegentliche Besucher zu unterstützen, auf dem neuesten Stand zu bleiben. Das Lesen von Digest-E-Mails ist eine gültige Art, auf einem Forum zu „lurken“, und man weiß nie, wann etwas das Interesse eines Nutzers an einer Beteiligung wecken wird.
Ähnlich werden standardmäßig unprivilegierte Nutzer, die nicht viel interagiert haben (Trust Level 0 ohne Beiträge), nach 730 Tagen ohne Login gelöscht. Setze „clean up inactive users after days“ auf 0, um das Löschen von Nutzern zu deaktivieren, wenn du möchtest, dass sie unbegrenzt lurken können, indem sie Digest-E-Mails lesen.
Erwäge, das yearly review-Plugin hinzuzufügen, das einmal pro Jahr einen Beitrag wie 2020: The Year in Review generiert und ihn schließlich an deine inaktiven Nutzer per E-Mail sendet, was sie ermutigen könnte, ihre Beteiligung zu erneuern.
Mail-Empfänger-Container
Richte einen dritten Container als Mail-Empfänger ein. Es stellt sicher, dass Bounces verarbeitet werden, macht deine Bounce-Verarbeitung unabhängig vom ausgehenden Mail-Anbieter und gibt dir die Option, per E-Mail zu antworten.
Stelle sicher, dass du SPF für das Vertrauen in deinen E-Mail-Absender eingerichtet hast; minimal eine Richtlinie wie v=spf1 +mx -all, wenn du über denselben MX sendest und empfängst, aber spezifischer könnte besser als Spam-Schutz vertraut werden. Erwäge auch DKIM.
Wenn du denselben Hostnamen zum Empfangen von E-Mails verwendest, solltest du SSL außerhalb deines Containers terminieren, wie für eine „Offline-Seite“ (siehe unten), und musst deine certbot-Zertifikate in den Container einbetten und den Container nach dem Ausführen von certbot neu starten.
Beende Benutzer-SSL-Verbindungen außerhalb des Containers
Es gibt zwei Möglichkeiten, SSL außerhalb des Containers zu terminieren, von denen beide erhebliche Vorteile gegenüber der Terminierung innerhalb des Containers bringen. Richte eine von ihnen ein, nachdem du discourse-setup erfolgreich abgeschlossen und dein Forum bootstrapped hast.
Externes nginx
Verwende nginx, das auf dem Host-System läuft, anstatt nur in einem Container, sowohl um eine Wartungsseite zu hosten als auch um IPv6-Adress-Logging zu unterstützen, wenn dein Host IPv6-Unterstützung hat. (Andernfalls werden alle IPv6-Verbindungen als von einer internen RFC1918-Adresse assoziiert mit deiner lokalen Docker-Virtual-Network-Schnittstelle protokolliert.) Diese Konfiguration wird eine temporäre Wartungsseite während der meisten Wartungsoperationen präsentieren, die schließlich zurück zur Seite umleiten wird, die ein Nutzer ansah.
Beachte, dass die Anweisungen auf dieser Seite (derzeit) vorschlagen, ein Paket namens letsencrypt zu installieren, aber es heißt jetzt normalerweise certbot. Wenn du den Anweisungen auf dieser Seite folgst, um --certonly zu verwenden, wirst du das nginx-Plugin für certbot nicht benötigen, aber die Installation des nginx-Plugins ist ein anderer Mechanismus. Auf CentOS-Derivaten ist das:
dnf config-manager --set-enabled crb
dnf install epel-release
dnf install certbot python3-certbot-nginx
systemctl enable --now certbot-renew.timer
Stelle sicher, dass certbot nginx und den Mail-Empfänger-Container neu startet, damit du nicht endest mit Browsern oder E-Mails, die den Verkehr mit deiner Site blockieren, weil sie weiterhin ein altes, abgelaufenes Zertifikat verwenden.
# systemctl edit certbot-renew
Für ein System ohne Mail-Empfänger fügte ich die beiden Zeilen hinzu:
[Service]
ExecStartPost=/bin/systemctl reload nginx
Auf einem System, auf dem ich einen separaten Mail-Empfänger-Container verwende, der auch das Zertifikat vom System teilt:
[Service]
ExecStartPost=/bin/systemctl reload nginx
ExecStartPost=/bin/sh -c 'cd /var/discourse && ./launcher restart mail-receiver'
Wenn du SELinux verwendest, sind die Ubuntu-Container nicht so eingerichtet, dass sie die nginx.http.sock-Datei mit httpd_sys_content_t labeln, damit externes nginx darauf zugreifen kann. Du hast zwei Möglichkeiten.
Die erste ist, nginx im permissiven Modus auszuführen, indem du SELinux-Schutz dafür entfernst: semanage permissive -a httpd_t
Das entfernt jedoch SELinux-Schutz von dem wahrscheinlich relevantesten Dienst! Um SELinux aktiviert zu halten, musst du nginx erlauben, auf die Fehlerseiten zuzugreifen und vom Proxying über einen Unix-Domain-Socket zu einem Port wechseln (was ein paar µs langsamer ist, aber für deine Nutzer nicht bemerkbar sein sollte).
Führe zuerst diese Befehle aus, um nginx zu erlauben, auf Fehlerseiten zuzugreifen:
semanage fcontext -a -t httpd_sys_content_t /var/www
restorecon -R -v /var/www
Dann in deiner app.yaml, kommentiere oder entferne - "templates/web.socketed.template.yml", exponiere Port 80 als einen anderen Port auf dem lokalen Rechner und baue den Container neu.
expose:
- "8008:80" # http
Verwende hier nicht https — du hast SSL im externen nginx terminiert, und der X-Forwarded-Proto-Header sagt Discourse, dass die Anfrage über https kam. Stelle sicher, dass Port 8008 (oder welcher anderer Port du auch gewählt hast) nicht durch deine Firewall-Einstellungen öffentlich exponiert ist.
Führe dann diesen Befehl aus, um nginx zu erlauben, über das Netzwerk zum Container zu verbinden:
setsebool -P httpd_can_network_connect 1
Modifiziere dann deine externe nginx-Konfiguration vom Proxying über nginx.http.sock zu http://127.0.0.1:8008 (oder deinem gewählten Port) und lösche den Standard-Connection: close-Header, damit das externe nginx nicht für jede Anfrage eine neue IP-Verbindung herstellen muss.
...
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" "";
...
Das Entfernen von web.socketed.template.yml entfernte auch die real_ip-Aufruf, also füge das zurück hinzu. Stelle sicher, dass der IP-Adressbereich, den du verwendest, sinnvoll ist; Docker’s Standard ist es, den 172.16* RFC1918-Adressraum zu verwenden, der nach Policy nicht im öffentlichen Internet geroutet wird. Füge zu deiner app.yml-Datei etwas wie dies in der run-Sektion hinzu, indem du einen oder mehrere der RFC1918-Adressräume oder was auch immer für dein Deployment geeignet ist, auswählst:
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;
Dies ist erforderlich, damit Rate-Limiting korrekt funktioniert, sowie um Registrierungs- und letzte-Nutzung-IP-Adressen für Nutzer zuzuordnen.
Für mehr Informationen:
Externer Dienst
Ich habe Fastly oder Cloudflare vor Discourse nicht konfiguriert, aber andere haben es getan, und im Gegensatz zu externem nginx, das auf dem Host läuft, können sie dir erlauben, eine Wartungsseite zu servieren, während das Host-System vollständig heruntergefahren ist, wie beim Neustart während eines Systemupdates auf deinem Host. Wenn das für dich sinnvoll ist, hier ist, wie du es tust:
Eile dich nicht zu S3-Uploads
Sei dir sehr sicher, dass du immer S3 (oder Äquivalent) für hochgeladene Bilder verwenden möchtest, bevor du enable_s3_uploads während der Einrichtung aktivierst oder später darauf migrierst. Sei dir bewusst, dass die Verwendung von S3 (s3_endpoint) mit seinem zugehörigen CDN (s3_cdn_url) für Bilder auch dazu führt, dass JavaScript über dieses CDN serviert wird. Die Migration von S3 zurück zu lokalem Speicher wird nicht unterstützt und es gibt keine konkreten Pläne, dies in naher Zukunft zu implementieren. Es ist eine „Einbahnstraße“, die nicht einmal durch ein vollständiges Backup und Restore rückgängig gemacht werden kann. Wenn du S3 oder Ähnliches verwendest, verwende nicht Digital Ocean Spaces statt S3. Es gibt Referenzen hier auf meta, dass es nicht zuverlässig ist.
Ich habe meine Site frühzeitig dazu gebracht, Bilder über Digital Ocean Spaces und sein zugehöriges CDN zu servieren, und ich musste Hunderte von Zeilen benutzerdefinierten Code schreiben, um zurück zu lokalem Speicher zu migrieren, wobei ich dabei geringfügige Schäden an meiner Discourse-Instanz verursachte, aufgrund der „Einbahnstraße“, die nicht gut verstanden wurde.
Für mehr Informationen:
Du musst S3-Uploads nicht aktivieren, um ein CDN für dein Discourse zu verwenden. Erwäge, ein unabhängiges CDN (z.B. Cloudflare, CloudFront, Fastly, GCS CDN) vor einem Discourse zu verwenden, das seine eigenen Bilder verwaltet. Es ist mein indirektes Verständnis, dass die Warnung, dass Cloudflare nicht empfohlen wird, aufgrund von „Rocket Loader“ modifiziertem JavaScript ist; und dass es derzeit, solange du „Rocket Loader“ nicht verwendest, korrekt funktioniert.
Discourse-Einstellungen für Moderation
Auf jeder Site, auf der Moderation aktiv ist, erwäge stark die enable_whispers-Konfiguration, die es Moderatoren und Administratoren erlaubt, über ein Thema inline zu sprechen. Außerdem haben Kategorie-Moderatoren in jüngeren Versionen von Discourse mehr Fähigkeiten erhalten. Es lohnt sich, enable_category_group_moderation zu kennen, wenn du Experten in verschiedenen Themen mit ihren eigenen Kategorien hast oder wenn du funktional getrennte Kategorien wie für Support hast.
Geolokalisierung kann hilfreich sein, wenn du versuchst zu verstehen, ob ein Konto legitim ist.
Die Discourse Templates-Funktion ist wirklich hilfreich für Moderatoren. Sie lässt dich an gemeinsamen Antworten zusammenarbeiten. Wir haben ein paar Dutzend auf Maker Forums. Es hat mehr Funktionen als das vorherige „Canned Responses“-Plugin, das es ersetzt.
Die User Notes-Funktion wird Moderatoren helfen, Notizen über Nutzer zu teilen. Du kannst diese für Dinge wie verwenden:
- „Behalte dieses Auge auf diesen Nutzer, sie könnten böswillig sein, weil …“
- „Während dieses Verhalten verdächtig erscheint, habe ich validiert, dass dies ein legitimer Nutzer ist, indem …“
- „Ich habe bereits ein Gespräch mit diesem Nutzer, um Bedenken anzusprechen, andere Moderatoren müssen nicht nachlegen.“
Informationszugänglichkeit
Das Discourse Solved-Plugin markiert nicht nur gelöste Probleme, damit Site-Besucher sie leichter identifizieren können, sondern ich verstehe, dass es auch Google-Suchergebnisse priorisieren könnte.
Öffentliche Informationen sind zugänglicher als private Informationen. Auf Maker Forums ermutigt unsere FAQ stark zu persönlichen Nachrichten und erinnert jeden daran, dass persönliche Nachrichten nicht wirklich privat sind. Standardmäßig können Nutzer jedoch die Nachricht sehen:
Du hast user 3 Mal geantwortet, wusstest du, dass du ihnen stattdessen eine persönliche Nachricht senden könntest?
Wenn du Nutzer wirklich ermutigen möchtest, zu persönlichen Nachrichten zu gehen, schlage ich vor, dass du zu Admin → Customize → Text gehst und die get_a_room-Vorlage änderst, um den Komma-Splice zu beheben.
Wenn du, wie Maker Forums, Konversationen öffentlich halten möchtest, um allen zu nutzen, kann Admin → Settings → Other → get_a_room_threshold höher gesetzt werden, wie 1000000.
Ähnlich, wenn du ein Forum hast, das Hilfe bietet, könnte der max_replies_in_first_day-Standardwert von 10 neue Nutzer in einer Konversation, die nach Hilfe fragt, in persönliche Nachrichten drängen, wenn sie ihr Budget an Antworten aufbrauchen. Erwäge, diese Einstellung zu erhöhen, um zu vermeiden, dass Konversationen in persönliche Nachrichten gedrängt werden.
Verbinde Nutzer, baue eine Community
Ein paar Plugins können helfen, Nutzer miteinander zu verbinden.
Wenn dein Forum nicht zu viele gleichzeitige Nutzer hat, erwäge das Who’s Online-Plugin, um den Menschen ein stärkeres Gefühl der Verbindung zu geben. Du möchtest vielleicht die Anzeige auf angemeldete Nutzer beschränken, möglicherweise nur diejenigen, die mindestens Trust Level 1 erreicht haben. Du kannst es nur verwenden, um Präsenz-Flair (whos_online_avatar_indicator) zu Avataren hinzuzufügen, indem du whose_online_minimum_display sehr hoch setzt und whos_online_hide_below_minimum_display true. Dies kann nützlich sein für Support-Foren, um schnelle Fragen und Antworten zu unterstützen und zu ermutigen, während es Nutzern hilft, Probleme zu lösen.
Allerdings kann ein Gefühl der Präsenz zweischneidig sein. Ein Nutzer, der zu einer anderen Zeit online ist als die Mehrheit der Forum-Nutzer, könnte sich einsam fühlen, oder das Forum könnte für sie wie eine „Geisterstadt“ wirken.
Wenn du Nutzer in vielen Ländern hast und möchtest, dass sie Hinweise darauf haben, wann sie wahrscheinlich verfügbar sind, erwäge das National Flags-Plugin und ermutige Nutzer, eine Nationalflagge in ihrem Profil zu setzen.
Ein kniffliges ist Übersetzung. Es wäre bequem, Menschen zu helfen, zu kommunizieren, wenn sie nicht dieselbe Sprache sprechen, aber derzeit (zum Zeitpunkt des Schreibens) gibt es keine Übersetzungsdienste mit kostenlosen Service-Tiers. Wenn du dich entscheidest, für Übersetzungsdienste zu bezahlen, kannst du Übersetzung mit dem Discourse Translator-Plugin aktivieren.
Backup
Für Systemdateien, erwäge mindestens zu sichern:
/var/discourse/containers(für Discourse-Konfigurationsdetails)/var/www(für Fehlerseiten)/etc/ssl(für letsencrypt-Konfiguration, um zu vermeiden, certbot als Teil der Wiederherstellung eines Backups bootstrappen zu müssen; anderenfalls musst du den SSL-Teil deiner nginx-Konfiguration auskommentieren, während du bootstrappst; dies funktioniert nur, wenn du die Backups aktuell hältst, weil die Zertifikate eine kurze Gültigkeit haben)/etc/systemd/system/backup-uploads.service(für Bilder-Backups zu S3)/usr/local/bin/mc(minio-client als Bilder-Backup-Tool, wenn du dich entscheidest, es zu verwenden)/root/.mc(Konfiguration für Bilder-Backup mit minio-client)/root/.ssh(eingehende SSH-Sitzungsauthentifizierung)
Einige dieser Dateien kannst du sichern, indem du sie in Git eincheckst und sie irgendwo außer Haus pushst. Wenn die Dateien, die du in Git eincheckst, Geheimnisse enthalten (wie Datenbankpasswörter), push sie definitiv nicht zu einem öffentlichen Repository. Alternativ könntest du das Kopieren von ihnen vom System und das Einchecken in Git auf einem überwachenden System, das du kontrollierst, scripten. Scripte dies häufig genug, um deine Backups von /etc/ssl frisch zu halten.
Das Ziel ist es, Backups sowohl im Falle eines Unglücks als auch um Aufzeichnungen von Änderungen im Falle eines Fehlers zu haben.
Eine bessere Alternative für die meisten dieser Dateien ist es, die kanonischen Kopien woanders zu halten und ein Tool wie Ansible zu verwenden, um die Konfiguration auf dem System zu warten, was es genauso einfach macht, nach einem Backup zu aktualisieren. Aber wenn du das tun wirst, hast du es wahrscheinlich ohne meine Hilfe herausgefunden!
Discourse-Konfiguration für Backup
-
Sichern von Thumbnails mit
include_thumbnails_in_backups. Ein Restore ohne Thumbnails dauert lange, um sie neu zu generieren. Wenn deine Site nicht viele Grafiken hat, nehmen die Thumbnails unbedeutenden Platz ein. Wenn deine Site grafikreich ist, könnte das Neu-Generieren von Thumbnails Tage dauern. Während Thumbnails neu generiert werden, werden E-Mail-Benachrichtigungen deaktiviert. Auf jeden Fall macht es keinen Sinn, Thumbnails von Backups auszuschließen. -
Schließe keine Bilder in Backups ein, wenn du viele Bilder hast. Dies wird Backups langsam und unhandlich machen. Sichern sie separat. Wenn du Bilder nach deinem Datenbank-Backup sicherst, werden deine Backups konsistent sein.
-
Richte ein, dass Backups irgendwie außer Haus gehen.
Diese Seite zeigt, wie du Datenbank-Backups zu S3 oder etwas wie S3 einrichtest:
Backup mit restic
Konfiguriere Discourse, um auf das Dateisystem zu sichern, und sichere dann vom Dateisystem zu einem entfernten Backup-Ziel mit restic. Hier ist ein Beispiel-Rezept.
# 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
Diese Details variieren je nach Restic-Ziel. Nicht alle verwenden AWS-Umgebungsvariablen, daher lesen Sie bitte die Restic-Dokumentation.
# cat > backup-config <<EOF
### Diese Details hängen davon ab, welches Restic-Ziel Sie konfigurieren, ändern Sie sie daher
export AWS_ACCESS_KEY_ID=ihre-schlüssel-id
export AWS_SECRET_ACCESS_KEY=geheim
export RESTIC_PASSWORD_FILE=/root/restic-password
export RESTIC_REPOSITORY=siehe-restic-dokumentation
EOF
# {$EDITOR:-nano} /root/restic-password
Sie müssen eine Kopie des Inhalts von /root/restic-password speichern, sonst können Sie die Backups nicht lesen! Verwenden Sie Ihr Passwort-Safe-Tool.
Erstellen Sie abschließend einige Dienste, initialisieren Sie das Restic-Repository und legen Sie einen Timer fest, damit die Backups starten.
# cat > /etc/systemd/system/backup.service <<EOF
[Unit]
Description=Backup an entferntes Ziel
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=Regelmäßige 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
Nach diesem Vorgang sollten Sie sehen können, dass Sie Ihr erstes Backup erstellt haben.
# restic snapshots
Ich habe erfolgreich Restic-Backups, die auf diese Weise erstellt wurden, verwendet, um einen Discourse-Server von einem System auf ein anderes zu migrieren, wobei ich den Befehl restic restore genutzt habe.
Streaming-Backups von MinIO-Images
Als Alternative zu Restic können Datenbank-Backups zwar in S3 gespeichert werden, es gibt jedoch kein separates S3-Image-Backup, das unabhängig vom Bereitstellen von Images aus S3 ist. Eine Alternative besteht darin, minio-client zu verwenden, um Images in jeden S3-ähnlichen Speicher zu kopieren. Dies kann viele S3-ähnliche Ziele sein, einschließlich S3 und MinIO, aber nicht DigitalOcean Spaces, da es auf dem Ceph-Dateisystem basiert, das die ListObjectsV2-API nicht auf die gleiche Weise implementiert wie S3.
Erstellen Sie in S3 einen Bucket, der öffentlichen Zugriff blockiert (Berechtigungen → Öffentlichen Zugriff blockieren ist der einfachste Weg, dies in AWS richtig einzurichten).
Installieren Sie minio-client (mc) auf irgendeine Weise. Hier ist eine Möglichkeit.
curl https://dl.min.io/client/mc/release/linux-amd64/mc > /usr/local/bin/mc && chmod +x /usr/local/bin/mc
Konfigurieren Sie minio-client mit einem Alias namens backup mit einem Befehl wie diesem:
# mc alias set backup https://s3.amazonaws.com ACCESSKEY SECRETKEY --api S3v4
# mc mirror /var/discourse/shared/standalone/uploads backup/UPLOADS-BACKUP-BUCKET
Erstellen Sie dann einen Dienst /etc/systemd/system/backup-uploads.service wie folgt:
[Unit]
Description=Nahezu zeitnahes Remote-Backup-Sync von 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
Beachten Sie, dass UPLOADS-BACKUP-BUCKET hier ein anderer Bucket sein sollte als der s3_backup_bucket, in den Sie Discourse konfigurieren, um Datenbank-Backups hochzuladen. Beachten Sie auch, dass der Pfad /var/discourse/shared/web_only/uploads sein wird, wenn Sie die Standard-Multi-Container-Bereitstellung verwenden.
# systemctl enable backup-uploads
# systemctl start backup-uploads
# journalctl -fu backup-uploads
Laden Sie ein Test-Image hoch und stellen Sie sicher, dass Sie Zeilen für das erfolgreiche Backup der ursprünglichen und optimierten Images sehen. Strg-C beendet den Follow-Modus in journalctl.
Wiederherstellung
Ich habe diesen Plan bis zur Erstellung dieses Dokuments noch nicht testen müssen. Diese Zusammenfassung könnte etwas übersehen.
- Stellen Sie alle gesicherten Dateien im Allgemeinen wieder her
- Starten Sie nginx (jetzt wird Ihre Wartungsseite angezeigt)
- Führen Sie eine normale Bereitstellung von Discourse mit den wiederhergestellten Dateien in
/var/discourse/containersdurch - Installieren Sie minio-client in
/usr/local/bin/mc, wenn Sie ihn nicht aus Backups wiederhergestellt haben - Wenn Sie
/root/mcnicht gesichert haben, richten Sie den Backup-Alias ein:# mc alias set backup https://s3.amazonaws.com ACCESSKEY SECRETKEY --api S3v4 # mc cp backup/UPLOADS-BACKUP-BUCKET /var/discourse/shared/app/uploads- Stellen Sie das neueste Datenbank-Backup wieder her; ich empfehle, Restore a backup from the command line zu verwenden
- Konfigurieren Sie das Backup von Uploads in S3 erst nachdem Sie bestätigt haben, dass die Website betriebsbereit ist, wie oben dokumentiert.
Streaming-PostgreSQL-Backups
In Zukunft werde ich möglicherweise eine Konfiguration erstellen, testen und bereitstellen, um die Verwendung von kontinuierlichem WAL-Archivierung zu ermöglichen, um nahezu sofortige Postgres-Backups mit minio-client unter Verwendung des archive-command in PostgreSQL zu streamen, ähnlich wie beim Streaming von Upload-Backups.
Leistungsüberwachung
Es gibt mindestens zwei Ansätze zur Leistungsüberwachung.
Prometheus-Container
Richten Sie Prometheus ein und legen Sie die Prometheus-Logs in /var/discourse/shared/prometheus, wenn Sie es auf demselben System ausführen. Prometheus-Dateien können groß werden, und Sie möchten nicht, dass sie das Root-Dateisystem füllen; außerdem möchten Sie sie wahrscheinlich mitnehmen, wenn Sie zu einem neueren Host-System wechseln (entweder ein Upgrade auf eine größere VM oder eine VM mit einer neueren Betriebssysteminstallation).
Wenn Sie Prometheus auf dem Discourse-System (oder anywhere else im öffentlichen Internet) bereitstellen, konfigurieren Sie die Sicherheit davor. Eine Option wäre eine nginx-Konfiguration wie diese:
location /prometheus/ {
auth_basic "Prometheus";
auth_basic_user_file /etc/nginx/prometheus-htpasswd;
proxy_pass http://localhost:9090/;
}
Sysstat
Wenn Prometheus zu viel ist, verwenden Sie stattdessen sysstat.
dnf install sysstat(oderapt install sysstatauf Debian und Ablegern)systemctl enable --now sysstatsystemctl enable --now sysstat-collect.timersystemctl enable --now sysstat-summary.timersystemctl edit sysstat-collect.timerund ändern SieOnCalendar=*:00/10inOnCalendar=*:00/2- Wenn
/etc/default/sysstatexistiert, ändern Siefalseintrue
Danach kann der Befehl sar Ihnen sagen, ob Sie gelegentlich Ressourcenprobleme haben.
Andere Ressourcen
Hier ist eine ergänzende (und kompaktere) Diskussion zur Verwendung von Discourse intern als primäre Form der internen Kommunikation.