MKJs Konfiguration für den Deployment von Meinungsäußerungen

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.

:warning: 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. :warning:

:warning: 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. :warning:

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

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/containers durch
  • Installieren Sie minio-client in /usr/local/bin/mc, wenn Sie ihn nicht aus Backups wiederhergestellt haben
  • Wenn Sie /root/mc nicht 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 (oder apt install sysstat auf Debian und Ablegern)
  • systemctl enable --now sysstat
  • systemctl enable --now sysstat-collect.timer
  • systemctl enable --now sysstat-summary.timer
  • systemctl edit sysstat-collect.timer und ändern Sie OnCalendar=*:00/10 in OnCalendar=*:00/2
  • Wenn /etc/default/sysstat existiert, ändern Sie false in true

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.

54 „Gefällt mir“

Hallo, vielen Dank für diese Anleitung.

Wie viele CPU-Kerne und wie viel RAM stehen Ihnen aktuell zur Verfügung?
Wie lauten Ihre aktuellen Einstellungen:

  db_shared_buffers: "xGB"
  db_work_mem: "xMB"
  UNICORN_WORKERS:

2 vCPUs (L5640 Xeon), 4 GB RAM – doch dank des massiven Imports haben wir mehr Inhalt pro gleichzeitigen Nutzer als typische Discourse-Instanzen, die vollständig organisch gewachsen sind. Wir haben selten mehr als 5 gleichzeitige Nutzer.

Ich habe db_work_mem in data.yml derzeit nicht gesetzt, aber es scheint in /etc/postgresql/13/main/postgresql.conf auf 10 MB eingestellt zu sein. In meiner data.yml habe ich db_shared_buffers: "768MB" gesetzt, doch jetzt sehe ich, dass in /etc/postgresql/13/main/postgresql.conf in meinem Datencontainer shared_buffers = 512MB steht, was mich überrascht. Offenbar habe ich meinen Datencontainer nach meiner letzten Änderung nicht neu aufgebaut. :roll_eyes: Ich habe die Konfigurationsänderung vorgenommen, bevor ich Prometheus hinzugefügt habe (was mehr Speicher verbraucht). Bevor ich die Einstellung ändere, werde ich Prometheus wahrscheinlich von dieser Server-Instanz entfernen.

In der App habe ich UNICORN_WORKERS: 4 gesetzt.

1 „Gefällt mir“

Danke @mcdanlj für all diese Goodies. Irgendwelche Ratschläge zur periodischen/geplanten Wartung? Wie wöchentliche/monatliche Neustarts? Oder Up/Down-Überwachung mit automatischem Neustart? Irgendeine andere periodische manuelle oder automatisierte Wartung?

1 „Gefällt mir“

@jaffadog Achte auf den Tag release-notes (es ist die Glocke oben rechts; ich benutze “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. Dies geschieht typischerweise monatlich für die App, was einen monatlichen Neustart abdeckt. Ich starte nicht häufiger nach einem Zeitplan neu. Außerdem:

Wenn Sie letsencrypt und mail_receiver verwenden, sollten Sie es wahrscheinlich so einrichten, dass mail_receiver nach Erhalt eines neuen Zertifikats neu gestartet wird.

Das ist alles, was mir im Moment einfällt. Danke für die Frage, und ich habe die Informationen zum Beobachten von release-notes und weitere Details zum Neustart in den Haupttext aufgenommen. Ich denke, dass jetzt alles vollständig im Originalbeitrag abgedeckt ist.

Ich habe die Update-Anweisungen erweitert, um Updates in /var/discourse abzurufen, um die Basis-Image-Version zu ändern. Da ich mir unter Update base image for polkit vulnerability angesehen habe, wurde mir klar, dass es irreführend sein könnte, diesen Schritt nicht explizit zu erwähnen. Ich betrachtete ihn zuvor als etwas, das Teil der Basisdokumentation ist. Das launcher-Skript enthält einen spezifischen Verweis auf die Basis-Image-Version, und bis Sie git pull ausführen, bauen Sie auf einem älteren Basis-Image auf und führen nicht das aus, was getestet wurde. (Suchen Sie nach image= in der Nähe des Anfangs der Datei.)

1 „Gefällt mir“

Es ist schlimmer als das: Es ist standardmäßig so konfiguriert, dass inaktive Konten der Stufe 0 nach einiger Zeit gelöscht werden. In meinem Fall war das wirklich nicht das, was ich wollte! Überprüfen Sie „Inaktive Benutzer nach Tagen bereinigen“ und setzen Sie es auf null oder eine wirklich große Zahl.

2 „Gefällt mir“

Ich habe mir das angesehen, aber soweit ich das verstanden habe, bedeutet es, dass sie nie auf den Ablauf „Bestätigen Sie Ihre E-Mail-Adresse“ reagiert haben und daher sowieso keine E-Mails erhalten würden. Ich glaube nicht, dass „inaktiv“ hier bedeutet „sich nicht auf der Website anmelden“, aber ich würde gerne wissen, ob ich falsch liege.

Nein, „inaktiv“ bedeutet hier nicht active=false.

Es bedeutet Benutzer, auf die alle folgenden Punkte zutreffen:

  • Vertrauensstufe 0
  • Keine Beiträge
  • Weder Administrator noch Moderator
  • Zuletzt vor mehr als X Tagen gesehen.

Und ja, diese Formulierung ist tatsächlich verwirrend, obwohl die Einstellung sie etwas erklärt („Vertrauensstufe 0 ohne Beiträge“).

8 „Gefällt mir“

Tatsächlich habe ich verschiedene Einstellungen verwechselt und hatte „unbenutzte gestagte Benutzer nach Tagen bereinigen“ im Sinn. Ich hatte „inaktive Benutzer nach Tagen bereinigen“ in den Maker-Foren schon vor langer Zeit auf Null gesetzt und hatte versäumt, es hier zu erwähnen; ich muss es bei meiner Überprüfung der geänderten Website-Einstellungen übersehen haben, als ich nach Dingen suchte, die von allgemeinem Interesse sein könnten. Vielen Dank an euch beide, @Ed_S und @RGJ! Ich habe den Beitrag um einen weiteren Absatz zum Aktivieren des Lurking ergänzt. :smiling_face:

4 „Gefällt mir“

Hallo @mcdanlj, danke für Ihre ausgezeichnete Einsicht, die Sie hier teilen. Bezüglich einer 2-Container-Installation bin ich verwirrt, wie diese einen Vorteil bei der Reduzierung von Ausfallzeiten bei Upgrades bietet. Auf meiner Testinstallation dauert ein Upgrade über die GUI-Oberfläche /admin/upgrade#/upgrade/all zwar mehrere Minuten, wie Sie beschreiben, aber die Website bleibt während des gesamten Vorgangs für Benutzer bedienbar.

Wenn Sie die beiden Containerinstallationen von der Befehlszeile aus neu erstellen müssen, können Sie das neue Image mit Bootstrap erstellen, während das alte weiterhin ausgeführt wird.

2 „Gefällt mir“

Wie üblich ist @pfaffman schneller als ich und kennt sich aus. :smiley:

Ich führe niemals Upgrades über die GUI durch. Auf diese Weise nehme ich jedes Mal, wenn ich ein Update durchführe, alle System-Sicherheitsupdates in den zugrunde liegenden Containern mit auf, auf denen Discourse läuft. Das bedeutet nicht, dass die Verwendung der GUI schlecht ist, noch ist es eine Empfehlung für alle anderen. Die GUI-Updates haben etwas geringere Ausfallzeiten (das Neustarten des Web-Containers unterbricht den Dienst kurzzeitig, was einer von mehreren Gründen ist, dies zusammen mit externem Nginx zu berücksichtigen), also ist es ein Kompromiss, und ich habe den weniger begangenen Weg gewählt.

Eine Single-Container-Installation hat öfter längere Ausfallzeiten, wenn Sie regelmäßig Updates für Sicherheitsupdates sowie gelegentliche Datenbankversions-Updates durchführen, da Discourse neue PostgreSQL-Funktionen nutzt. Ohne tatsächliche Daten zu prüfen, habe ich das Gefühl, dass es einen Grund gibt, dies 3-4 Mal pro Jahr neu zu erstellen. Wenn diese Ausfallzeit aus Ihrer Sicht in Ordnung ist, gibt es nicht viel Grund, die Komplexität der 2-Container-Bereitstellung in Kauf zu nehmen.

4 „Gefällt mir“

Das ist sehr nett, aber hier geht es um Ihre Meinung. :wink:

Ich auch nicht. Außer mit meinem Dashboard, das eine Menge zusätzlicher Dinge im Container hat (wie Ansible und ich kann mich nicht mehr genau erinnern, was alles), und wenn jemand ein Upgrade über dashboard.literatecomputing.com durchführt und ich dann diesen Container zerstöre, wird sein Rebuild beendet, was potenziell problematisch ist. Also habe ich in letzter Zeit ein paar mehr docker_manager-Upgrades durchgeführt, und sie sind ziemlich raffiniert.

Nicht wirklich. Es ist zumindest meistens so, dass docker_manager Sie dazu zwingt, ein neues Basis-Image zu erhalten, wenn es eines gibt (zumindest versucht es das).

Das kommt ungefähr hin. FWIW, und ich empfehle es nicht, aber ich habe mit einer Reihe von Leuten interagiert, die jahrelang ohne Probleme keine Upgrades durchgeführt haben.

1 „Gefällt mir“

Ja, es steht außer Frage, dass die In-Container-Updates gut implementiert sind!

Ja, das meinte ich. :tada:

2 „Gefällt mir“

Hallo nochmal, vielen Dank für Ihre Einblicke. Ich versuche immer noch zu entscheiden, was ich für mein Produktions-Setup tun werde. Ich verstehe theoretisch, warum eine 2-Container-Installation zu weniger Ausfallzeiten führen würde. Aber ich sehe immer noch kaum Ausfallzeiten mit dem GUI-Update-Mechanismus. Ich habe es gerade gestoppt, ich hatte ein Docker-Manager-Update und Discourse war 22 Commits zurück. Der gesamte Vorgang dauerte weniger als 5 Minuten und während des gesamten Vorgangs war das Forum voll funktionsfähig. Zugegeben, es gab dieses Mal keine PostgreSQL-Updates, aber wenn es notwendig wäre, diese ebenfalls zu aktualisieren, dann würde ich die maximale Ausfallzeit auch mit der 2-Container-Methode in Kauf nehmen, richtig? Wenn ich also richtig verstehe, reduziert die 2-Container-Methode nur die Ausfallzeit, wenn ein SSH-Login und ein App-Container-Neubau aufgrund einer Konfigurationsänderung (Hinzufügen/Entfernen von Plugins usw.) erforderlich sind? Ich gehe nicht von häufigen Änderungen an meiner Produktionskonfiguration aus, daher sehe ich in meinem Fall keine potenzielle Reduzierung der Ausfallzeit. Oder muss ich mich auch per SSH anmelden und die Container neu erstellen, um bestimmte Arten von Feature-/Sicherheitsupdates anzuwenden?

Das ist in Ordnung.

Ja, Sie haben die volle Ausfallzeit bei jeder Aktualisierung von PostgreSQL (alle ein oder zwei Jahre, plus Sicherheitsupdates für PostgreSQL selbst, obwohl diese nicht so häufig waren).

Bevor ich wechselte, hatte ich ein paar Fehler bei den GUI-Updates, erinnere mich aber nicht mehr an die Details; alte Geschichte.

Die GUI-Updates aktualisieren nicht das Basis-Image, sodass alle Sicherheitsupdates in der bereitgestellten Software, wie z. B. der Bildverarbeitung, dort nicht angewendet werden.

Ich baue den App-Container gerne schnell als meinen normalen Modus um, um Sicherheitsupdates für den App-Container zu erhalten, sobald sie verfügbar sind, damit ich das niemals auf eine 10-minütige Ausfallzeit zum Neuerstellen von allem verschieben würde. Deshalb ist git pull im Launcher Teil des ersten Schritts, um jedes Update anzuwenden; damit, wenn das Basis-Image mit Dingen wie Bildverarbeitungsprogrammen aktualisiert wurde, diese angewendet werden, ohne dass ich überhaupt darüber nachdenken muss, ob Sicherheitsupdates angewendet werden müssen. :smiling_face:

Aber letztendlich finde ich persönlich den Zwei-Container-Ansatz für mich einfacher, und ich versuche absolut nicht, andere Leute davon zu überzeugen. Wenn es Ihnen aufgrund Ihres Wissens und Ihrer Erfahrung nicht einfacher erscheint, tun Sie es nicht, nur weil mein persönlicher, meinungsbasierter Leitfaden ihn in einem bestimmten Kontext als nützlich identifiziert. :grin:

2 „Gefällt mir“

Verstanden! :wink: Ich habe auch starke Meinungen zu technischen Implementierungsdetails, aber ich schätze Ihre zusätzliche Perspektive.

Hmm, ist das also immer noch der Fall?

Jedenfalls ist meiner Erfahrung nach mit traditionellen Foren, die ohne Containerisierung auf einem LAMP/LEMP-Stack installiert sind, der typische Schwachpunkt / Angriffsvektor, der zu kompromittierten Websites in der realen Welt führt, fast immer im Code der Webanwendung oder in einem ihrer Webentwicklungs-Frameworks zu finden. Daher neige ich dazu, den Updates des Discourse-Codebases, die anscheinend über die GUI gehandhabt werden, mehr Dringlichkeit beizumessen, also lehne ich mich wohl in diese Richtung.


Übrigens, zum Thema Ausfallzeiten, ein kleiner Hinweis auf Clear Linux: Ich habe es wegen seiner Low-Level-Optimierungen bei reinem Zahlenjonglieren getestet, um meinen riesigen Forenimportprozess um ein paar Stunden zu verkürzen. Es mag tatsächlich einige Geschwindigkeitsverbesserungen für diesen Fall geben, aber im Allgemeinen ist es heiliger Bimbam, es ist verrückt schnell beim Neustart, besonders als KVM-Gast. Auf der billigsten VPS-Stufe kann ich in kaum 5 Sekunden neu starten und mich wieder bei SSH anmelden. Daher freue ich mich darauf, dies zu nutzen, wenn es wichtige Host-OS-Updates gibt.

Ja. Aber ein paar Mal im Jahr müssen Sie einen Befehlszeilen-Neustart durchführen, weil eine Komponente im Container aktualisiert wurde. Und dann haben Sie 5-15 Minuten Ausfallzeit. Ich mache so ziemlich alle Upgrades über die Befehlszeile (außer auf meinem Dashboard, wo ich vielleicht mehrmals am Tag nur das Dashboard-Plugin aktualisiere), und ich habe eine Reihe von Kunden, für die ich diese Befehlszeilen-Updates durchführe, wenn sie erforderlich sind (vermutlich führen sie Updates über die Webschnittstelle durch, aber oft tun sie das nicht).

2 „Gefällt mir“

Benachrichtigt das Discourse-Dashboard speziell über diese Art von erforderlichem Update? Oder sollte ich die PSAs von Debian im Auge behalten?