Ich betrete seit einigen Jahren ein Discourse-Forum mit einer beträchtlichen Menge an Inhalten und vielen Bildern. Maker Forums hat über 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, was ich gewünscht hätte, wenn 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, die Wissen über Linux voraussetzen. Wenn das Lesen dieses Leitfadens für dich aufklärend wirkt, könntest du das Zielpublikum sein. Wenn das Lesen dieses Leitfadens für dich verwirrend wirkt, bist du wahrscheinlich nicht das Zielpublikum. Wenn das Lesen dieses Leitfadens für dich wie Arbeit wirkt, erwäge bitte, CDCK oder @pfaffman zu bezahlen, damit sie Discourse für dich betreiben; sie wissen, was sie tun. Oder beginne mit einer kostenlosen discourse.group-Seite und zahle dann für das, wozu 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 etwas von dir kaputtgeht (dein Discourse-Forum, dein Host-System oder dein Herz), behältst du beide Teile, mit all den scharfen Kanten. Ich plane nicht, irgendeine Form von Support für den Inhalt dieses Beitrags zu bieten.
Ich plane (garantiere aber nicht), dieses Dokument mit meinen Praktiken für die Discourse-Instanzen, an deren Wartung ich beteiligt bin, auf dem neuesten Stand zu halten. Dies ist in Form von Ratschlägen geschrieben, aber ich beabsichtige es primär als Ratschlag für mich selbst und für alle Administratoren, die Discourse-Deployments übernehmen, für die ich verantwortlich war. Andernfalls solltest du es als einen Ausgangspunkt für deine eigene Forschung betrachten, um festzustellen, wie du Discourse bereitstellen möchtest.
System-Einrichtung
Verwende ein CentOS-deriviertes 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 laufen lassen, weil ich der Meinung bin, dass sein Sicherheitsmodell dem von Docker überlegen ist. Allerdings werden Discourse-Deployments nur auf Docker unterstützt, und du wirst ein ziemlicher Pionier sein, wenn du versuchst, es auf etwas anderem laufen zu lassen. (Es könnte irgendwann mit Podman und 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-derivierten 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 --allowerasing 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 er 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 mit Passphrase 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, so dass du sie nur einmal pro Booten eingeben musst. Windows ist nicht so bequem; du könntest erwägen, Pageant mit PuTTY zu verwenden, um das Gleiche zu tun.
Überprüfe zunächst, ob eingehende SSH-Verbindungen ohne Passwort funktionieren. Nur 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 generell 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 Platz, wie du für Bilder brauchst; füge mehr Speicherplatz hinzu, wenn du prometheus verwenden wirst. Wenn das Gerät später leicht erweitert werden kann (wie LVM oder jeder Cloud-Block-Speicher wie AWS Elastic Block Storage), kannst du es überwachen und nach Bedarf vergrößern; sonst sei von Anfang an großzügig. Wenn du ein Netzwerk-Speicher-Block-Gerä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-Speicher-Block-Gerä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 es 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, Schlüsseldateien darauf kopieren, die alte VM stoppen, das /var/discourse/shared-Volume an die neue VM anhängen und innerhalb weniger 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 den 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 willst auch plenty of space für System-Updates verfügbar haben. Wenn du nicht genug Festplattenspeicher hast, ist das 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 stattdessen seine Funktion; es wird berichtet, dass es nicht mit force_https in Discourse kompatibel ist.)
Kernel-Konfiguration
Redis (eine der Schlüsselkomponenten, auf denen Discourse basiert) empfiehlt dringend, transparente große Seiten zu deaktivieren, wenn On-Disk-Persistenz verwendet wird (was Discourse tut), und ich erlaube auch Memory-Overcommit.
echo 'w /sys/kernel/mm/transparent_hugepage/enabled - - - - never
w /sys/kernel/mm/transparent_hugepage/defrag - - - - never' > /etc/tmpfiles.d/thp.conf
systemd-tmpfiles --create
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, das monatlich empfohlen wird, typischerweise zu einer 10-15-minütigen Ausfallzeit, wenn es von der Kommandozeile aus durchgeführt wird, was für einige Updates notwendig ist, einschließlich solcher, die die Tools aktualisieren, auf denen Discourse basiert, für Sicherheit oder 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
# my preference to use app.yml but you might stick with web_only.yml, read 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, kaum merkbar; 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 zu installieren; es ist nur ein kleiner Ausfall statt ungefähr 15 Minuten, um alles neu zu bauen. 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 im Jahr in der Praxis) werden die Datenbankmigrationen, die am Ende der bootstrap-Phase durchgeführt werden, mehr oder weniger schwere 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 ein- oder zweimal im 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 musst, 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 standardmäßig, aber ich schätze die Benutzerfreundlichkeit immer wieder. Allerdings war es extra 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 zwingt, eine Migration zu einer neuen Konfiguration für das Verbinden deiner Container durchzuführen:
Wenn du 4 GB oder mehr Speicher oder mehrere CPUs hast, lies den Rat unter:
Update-Zeitplan
Beobachte das #release-notes-Tag (Klicke auf release-notes und klicke auf die Glocke oben rechts; ich verwende „Watching First Post“) 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, das die Datenbank aktualisiert, nicht liest, könntest du Datenbank-Update-Anweisungen in den Release-Notes, die du nicht gelesen hast, übersehen.
Mail ist immer noch einer der Schlüssel, um Menschen zu verbinden. 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ückzukommen, wenn sie etwas Neues und Interessantes sehen. Ich habe es für Maker Forums erheblich länger gemacht, um gelegentliche Besucher auf dem Laufenden zu halten. Das Lesen von Digest-E-Mails ist eine gültige Möglichkeit, auf einem Forum zu „lurken“, und du weißt nie, wann etwas das Interesse eines Nutzers an der Teilnahme wecken könnte.
Ähnlich werden standardmäßig unprivilegierte Nutzer, die nicht viel interagiert haben (Trust Level 0 ohne Beiträge), nach 730 Tagen ohne Anmeldung 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 unendlich lange Digest-E-Mails lesen können.
Erwäge, das yearly review-Plugin hinzuzufügen, das einmal im 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 Teilnahme zu erneuern.
Mail-Empfänger-Container
Richte einen dritten Container als Mail-Empfänger ein. Er stellt sicher, dass Bounce-Verarbeitung durchgeführt wird, 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-Sender eingerichtet hast; mindestens eine Richtlinie wie v=spf1 +mx -all, wenn du durch 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 beenden, 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 beenden, von denen beide erhebliche Vorteile gegenüber dem Beenden 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, nicht 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, die mit deiner lokalen Docker-Virtual-Network-Schnittstelle verbunden ist, protokolliert.) Diese Konfiguration wird eine temporäre Wartungsseite während der meisten Wartungsoperationen anzeigen, 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, so dass du nicht endest mit Browsern oder E-Mails, die den Verkehr mit deiner Seite blockieren, weil sie weiterhin ein altes, abgelaufenes Zertifikat verwenden.
# systemctl edit certbot-renew
Für ein System ohne Mail-Empfänger habe ich die beiden Zeilen hinzugefügt:
[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 für externes nginx zu markieren, um darauf zugreifen zu können. Du hast zwei Möglichkeiten.
Die erste ist, nginx im permissiven Modus zu laufen, um SELinux-Schutz dafür zu entfernen: semanage permissive -a httpd_t
Allerdings entfernt das SELinux-Schutz von dem, was wahrscheinlich der relevanteste Dienst ist! 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 zunächst 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 die - "templates/web.socketed.template.yml", exponiere Port 80 als einen anderen Port auf dem lokalen Computer und baue den Container neu.
expose:
- "8008:80" # http
Verwende hier nicht https — du hast SSL im externen nginx beendet, und der X-Forwarded-Proto-Header teilt Discourse mit, dass die Anfrage über https eingegangen ist. Stelle sicher, dass Port 8008 (oder welcher andere Port du auch gewählt hast) nicht öffentlich durch deine Firewall-Einstellungen exponiert ist.
Führe dann diesen Befehl aus, um nginx zu erlauben, über das Netzwerk mit dem 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, so dass das externe nginx nicht für jede Anfrage eine neue IP-Verbindung aufbauen 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 wieder hinzu. Stelle sicher, dass der IP-Adressbereich, den du verwendest, Sinn macht; Docker’s Standard ist, den 172.16* RFC1918-Adressraum zu verwenden, der nach Richtlinie nicht im öffentlichen Internet geroutet wird. Füge zu deiner app.yml-Datei etwas wie dies im run-Abschnitt hinzu, indem du einen oder mehrere der RFC1918-Adressräume oder was auch immer für dein Deployment angemessen 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 ausgefallen ist, wie beim Neustart während eines System-Updates auf deinem Host. Wenn dies für dich sinnvoll ist, hier ist, wie du es machst:
Eile nicht zu S3-Uploads
Sei dir sehr sicher, dass du immer S3 (oder Äquivalent) für hochgeladene Bilder verwenden willst, 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 „Einweg-Tür“, die nicht einmal durch ein vollständiges Backup und Wiederherstellung 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 Seite frühzeitig dazu gebracht, Bilder über Digital Ocean Spaces und sein zugehöriges CDN zu servieren, und ich musste hunderte Zeilen benutzerdefinierten Code schreiben, um zurück zu lokalem Speicher zu migrieren, wobei ich dabei meinen Discourse-Instanz geringfügigen Schaden zufügte, aufgrund der „Einweg-Tür“, 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 zweithändiges Verständnis, dass die Warnung, dass Cloudflare nicht empfohlen wird, auf “Rocket Loader” JavaScript modifiziert zurückzuführen ist; und dass zu diesem Zeitpunkt, solange du „Rocket Loader“ nicht verwendest, es 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 in der Zeile zu sprechen. Außerdem haben Kategorie-Moderatoren in den letzten Versionen von Discourse mehr Fähigkeiten erhalten. Es ist wert, enable_category_group_moderation zu beachten, 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 bei gemeinsamen Antworten zusammenarbeiten. Wir haben ein paar Dutzend bei 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 diesen Nutzer im Auge, er könnte 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 nachziehen.”
Informationszugänglichkeit
Das Discourse Solved-Plugin markiert nicht nur gelöste Probleme, so dass Site-Besucher sie leichter identifizieren können, aber ich verstehe, dass es auch Google-Suchergebnisse priorisieren könnte.
Öffentliche Informationen sind zugänglicher als private Informationen. Auf Maker Forums entmutigt unsere FAQ stark persönliche Nachrichten und erinnert jeden daran, dass persönliche Nachrichten nicht wirklich privat sind. Allerdings können Nutzer standardmäßig die Nachricht sehen:
Du hast 3 Mal auf user geantwortet, wusstest du, dass du ihnen stattdessen eine persönliche Nachricht senden könntest?
Wenn du wirklich möchtest, dass Nutzer zu persönlichen Nachrichten 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, möchtest, dass Konversationen öffentlich bleiben, 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 mehr ein Gefühl der Verbindung zu geben. Du möchtest vielleicht die Anzeige auf angemeldete Nutzer beschränken, möglicherweise nur auf 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 auf true setzt. Dies kann für Support-Foren nützlich sein, 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 zwei Klingen haben. Ein Nutzer, der zu einer anderen Zeit als die Mehrheit der Forum-Nutzer online ist, könnte sich einsam fühlen, oder das Forum könnte für sie wie eine „Geisterstadt“ erscheinen.
Wenn du Nutzer in vielen Ländern hast und möchtest, dass sie Hinweise darauf haben, wann sie wahrscheinlicher verfügbar sind, erwäge das National Flags-Plugin, und ermutige Nutzer, eine Nationalflagge in ihrem Profil zu setzen.
Ein schwieriger 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-Ebenen. 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 das Backup von:
/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; sonst 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 kurze Gültigkeit haben)/etc/systemd/system/backup-uploads.service(für das Backup von Bildern nach S3)/usr/local/bin/mc(minio-client als Bild-Backup-Tool, wenn du es verwendest)/root/.mc(Konfiguration für Bild-Backup mit minio-client)/root/.ssh(eingehende SSH-Sitzungsauthentifizierung)
Einige dieser Dateien kannst du durch das Einchecken in Git und das Pushen an einen externen Ort sichern. Wenn die Dateien, die du in Git eincheckst, Geheimnisse enthalten (wie Datenbank-Passwörter), pushe sie definitiv nicht in ein öffentliches Repository. Alternativ könntest du das Kopieren von ihnen vom System und das Einchecken in Git auf einem überwachenden System, das du kontrollierst, skripten. Skript 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 pflegen, 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
-
Backup von Thumbnails mit
include_thumbnails_in_backups. Eine Wiederherstellung 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. Backup sie separat. Wenn du Bilder nach deinem Datenbank-Backup backupst, werden deine Backups konsistent sein.
-
Richte ein, dass Backups irgendwie offsite gehen.
Diese Seite zeigt, wie man Datenbank-Backups nach S3 oder etwas wie S3 einrichtet:
Backup mit restic
Konfiguriere Discourse, um auf das Dateisystem zu backupen, und backup 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, also lesen Sie 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-hier
export AWS_SECRET_ACCESS_KEY=dasselbe
export RESTIC_PASSWORD_FILE=/root/restic-password
export RESTIC_REPOSITORY=sehen-sie-die-restic-dokumentation
EOF
# {$EDITOR:-nano} /root/restic-password
Sie müssen eine Kopie dessen speichern, was Sie in /root/restic-password eingefügt haben, sonst können Sie die Backups nicht lesen! Verwenden Sie Ihr Passwort-Tresor-System.
Erstellen Sie schließlich 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 auf 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 Systembackups
[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 Prozess sollten Sie sehen können, dass Sie Ihr erstes Backup erstellt haben.
# restic snapshots
Ich habe erfolgreich Restic-Backups verwendet, die auf diese Weise erstellt wurden, um einen Discourse-Server von einem System auf ein anderes zu übertragen, indem ich den Befehl restic restore verwendet 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 für das Bereitstellen von Images aus S3. Eine Alternative ist die Verwendung von minio-client, 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 so implementiert wie S3.
Erstellen Sie in S3 einen Bucket, der öffentlichen Zugriff blockiert (Berechtigungen → Öffentlichen Zugriff blockieren ist der einfache Weg, um dies in AWS richtig einzurichten).
Installieren Sie minio-client (mc) irgendwie. 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 Testbild hoch und stellen Sie sicher, dass Sie Zeilen für das erfolgreiche Backup der ursprünglichen und optimierten Bilder sehen. Strg+C beendet den Follow-Modus in journalctl.
Wiederherstellung
Bisher habe ich diesen Plan 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/containers durch
- 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, dass Sie Restore a backup from the command line verwenden
- Konfigurieren Sie erst nachdem Sie bestätigt haben, dass die Seite betriebsbereit ist, das Backup der Uploads in S3 wie oben dokumentiert neu.
Streaming-PostgreSQL-Backups
In Zukunft kann ich 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 bei Streaming-Upload-Backups.
Leistungsüberwachung
Es gibt mindestens zwei Ansätze zur Leistungsüberwachung.
Prometheus-Container
Richten Sie Prometheus ein und legen Sie die Prometheus-Protokolle 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; Sie möchten sie wahrscheinlich auch mitnehmen, wenn Sie zu einem neueren Host-System wechseln (entweder durch Upgrade auf eine größere VM oder eine VM mit einer neueren Betriebssysteminstallation).
Wenn Sie Prometheus auf dem Discourse-System (oder irgendwo 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/10zuOnCalendar=*:00/2- Wenn /etc/default/sysstat existiert, ändern Sie
falsezutrue
Danach kann der Befehl sar Ihnen sagen, ob Sie ab und zu an Ressourcenmangel leiden.
Andere Ressourcen
Hier ist eine ergänzende (und kompaktere) Diskussion über die Verwendung von Discourse intern als primäre Form der internen Kommunikation.