MKJs Konfiguration für die Deployment-Strategie von Discourse

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.

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

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

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/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, 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 (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 zu OnCalendar=*:00/2
  • Wenn /etc/default/sysstat existiert, ändern Sie false zu true

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.

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?