Hinweis: Dies ist eine Übersetzung meines Beitrags (Englisch), die die Implementierung des Kommentarservers beschreibt, der auf derselben Site verwendet wird, auf der sich das Original befindet.
TL; DR-Version: Ich habe die Commento-Serverkonfiguration entwickelt, die einfach und einfach im halbautomatischen Modus bereitgestellt werden kann. Kopieren Sie dieses Repository von GitHub in sich selbst und folgen Sie den Anweisungen in README .
Vor einiger Zeit wollte ich Disqus - das vielleicht häufigste System zum Hinzufügen von Kommentaren zu Seiten - unwiderstehlich in ein freies und offenes Commento ändern.
Das Problem bei Disqus ist, wie bei vielen anderen "kostenlosen" Produkten, dass das Produkt in diesem Fall der Benutzer ist - das heißt Sie. Darüber hinaus „bereichert“ Disqus jede Seite, auf der es verwendet wird, mit Megabyte an Skripten und mehr als hundert zusätzlichen HTTP-Anforderungen.
Außerdem werden in der kostenlosen Version Anzeigen geschaltet, mit denen Sie "nur" 9 US-Dollar pro Monat auszahlen können (Plus-Plan). Dies allein reicht aus, um etwas Besseres finden zu wollen.
Irgendwann bin ich auf diesen Beitrag gestoßen und habe herausgefunden, dass es einen kostenlosen Kommentarserver namens Commento gibt . Durch einen glücklichen Zufall wurde Commento erst kürzlich vollständig geöffnet - bevor es in zwei Versionen erhältlich war: Free Community und Commercial Enterprise . Dank seines Entwicklers Adhityaa Chandrasekar.
Commento ist um Größenordnungen effizienter als Disqus, die typische Größe der zusätzlichen Last beträgt etwa 11 KB , plus die Kommentare selbst natürlich. Ungefähr die gleiche Situation mit den erforderlichen HTTP-Anforderungen.
Ein weiteres Plus des Commento-Servers ist, dass er sehr schnell ist, da er in Go geschrieben ist.
Nun, als Kirsche auf dem Kuchen hat er eine Menge Kommentare von Disqus, wovon könnte er sonst noch träumen?
Für nicht fortgeschrittene (technisch) Benutzer bietet Commento einen einsatzbereiten Cloud-Dienst auf commento.io . Der Autor bietet Ihnen an, die monatliche Gebühr selbst zu wählen, sie darf jedoch "aus technischen Gründen" nicht unter 3 US-Dollar liegen.
Herr Chandrasekar bietet auch großzügig ein kostenloses Konto auf Commento.io an, um „nicht triviale Patches“ für das Produkt zu erhalten.
Nun, ich habe die dritte Option gewählt: den Commento-Server selbst zu erhöhen. In diesem Fall sind Sie von niemandem abhängig (außer natürlich vom Hoster), und ich liebe die Unabhängigkeit.
Schwierigkeiten
Ich bin ein großer Fan von Docker-Containern und verwende häufig Docker Compose , ein Tool zum Verwalten von Gruppen mehrerer verwandter Container. Commento verfügt über ein gebrauchsfertiges Docker-Image in der GitLab-Containerregistrierung.
Daher reifte die Entscheidung, Container zu verwenden, von selbst - aber zunächst mussten einige Dinge entschieden werden.
Schwierigkeit Nr. 1: PostgreSQL
Für Commento ist eine relativ neue Version des PostgreSQL-Servers erforderlich. Leider werden keine anderen SQL-Server unterstützt.
Nun, wir lassen immer noch alles in Containern laufen, also ist es ziemlich einfach.
Schwierigkeit Nr. 2: Keine HTTPS-Unterstützung
Commento selbst ist ein Webserver, unterstützt jedoch nur das unsichere HTTP-Protokoll.
Es ist zu beachten, dass diese Vorgehensweise heutzutage weit verbreitet ist: In diesem Fall ist der Server hinter dem Reverse-Proxy versteckt, der auch das SSL-Offloading durchführt. Die Sache ist, dass SSL / HTTPS-Unterstützung in diesem Fall schließlich in der Werft 2019 absolut notwendig ist und es sehr schwierig sein wird, Versuche zu versuchen, einen Benutzer unter Verwendung eines ungesicherten Internetprotokolls zu autorisieren.
Ich habe mich für den Nginx- Server entschieden. Erstens hatte ich beträchtliche Erfahrung damit, und zweitens ist er sehr schnell, wirtschaftlich und stabil. Und veröffentlicht die offiziellen Builds von Docker-Images .
Die zweite Zutat im HTTPS-Rezept ist das SSL-Zertifikat für die Domain. Ich bin EFF und Mozilla auf ewig dankbar, dass sie die Let's Encrypt Certificate Authority erstellt haben , die jeden Monat Millionen kostenloser Zertifikate ausstellt.
Let's Encrypt bietet auch ein kostenloses Befehlszeilenprogramm namens certbot , das das Abrufen und Aktualisieren eines Zertifikats erheblich vereinfacht. Nun, und natürlich ein Docker-Image für ihn!
Schwierigkeit Nr. 3: Certbot-Hühnerei-Problem
Aber dieser Trick ist schwieriger.
Wir möchten in der Konfiguration unseres Reverse-Proxys auf Nginx auf das SSL-Zertifikat verweisen, was bedeutet, dass es ohne Zertifikat einfach nicht gestartet werden kann. Um ein SSL-Zertifikat für eine Domain zu erhalten, benötigen Sie gleichzeitig einen funktionierenden HTTP-Server, mit dem Let's Encrypt Ihren Besitz dieser Domain nachweist.
Ich habe es geschafft, dieses Problem zu lösen, und es scheint mir ziemlich elegant:
- Zunächst wird ein ungültiges Dummy-Zertifikat generiert, dessen einziger Zweck darin besteht, Nginx starten zu lassen.
- Nginx und certbot erhalten gemeinsam ein neues, jetzt gültiges Zertifikat.
- Sobald das Zertifikat empfangen wurde, wechselt certbot in den „Standby-Modus“ und wacht alle 12 Stunden auf, um zu überprüfen, ob es aktualisiert werden muss - gemäß den Empfehlungen von Let's Encrypt.
- Wenn der Moment gekommen ist und das Zertifikat erneuert wurde, signalisiert certbot Nginx, neu zu starten.
Schwierigkeit Nr. 4: Etwas muss erhalten bleiben
Ich vermute sehr, dass Sie möchten, dass Benutzerkommentare nach einem Neustart oder einem Systemupdate gespeichert werden.
Damit Let's Encrypt Sie nicht aufgrund zu häufiger Anfragen sperrt, sollten Sie die erhaltenen Zertifikate für das gesamte Ablaufdatum aufbewahren.
Beide Punkte wurden in der vorgeschlagenen Konfiguration unter Verwendung der Volumes des Dockers gelöst, die von systemd beim ersten Start von Commento automatisch erstellt wurden. Volumes werden als "extern" markiert, sodass Docker sie überspringt, wenn Container mit docker-compose down -v
.
Bring alles zusammen
Jetzt können Sie sehen, wie alles zusammenarbeitet.
Die folgende Abbildung zeigt die Interaktion und den Verkehr zwischen den vier Containern:

Ich habe die depends_on
Option Docker Compose depends_on
um sicherzustellen, dass die Container in der richtigen Reihenfolge beginnen.
Wenn Sie nur Ihren eigenen Commento-Server starten möchten, können Sie den Rest des Artikels überspringen und direkt zum Code auf GitHub wechseln .
Nun, ich werde später ausführlicher auf diese Implementierung eingehen.
Wie funktioniert das alles?
Datei erstellen
Wie Sie im Bild oben sehen können, besteht meine „Komposition“ aus vier Diensten:
certbot
- Dienstprogramm certbot
von EFFnginx
- Reverse Proxy, der SSL-Offloading implementiertapp
- Commento Serverpostgres
- PostgreSQL-Datenbank
Die docker-compose.yml
enthält Deklarationen des eigenen Docker-Netzwerks mit dem Namen commento_network
und drei Volumes, von denen zwei extern sind ( docker-compose.yml
außerhalb von Compose erstellt werden müssen):
commento_postgres_volume
speichert PostgreSQL-Serverdaten für Commento: Benutzer, Moderatoren, Kommentare usw.certbot_etc_volume
enthält Zertifikate, die von certbot
empfangen wurden.
Nginx
Der Nginx-Container basiert auf einem einfachen offiziellen Image, das auf Alpine basiert, und verwendet das folgende Skript zum Ausführen:
- Zeile 3 ( ARRGHHH, Habr unterstützt die Anzeige von Zeilennummern im Code nicht - ca. Transl. ) Ein Interrupt-Handler wird registriert, damit Nginx und der Hintergrundüberwachungsprozess die Arbeit erfolgreich abschließen, wenn der Container stoppt.
- Zeile 27 ruft die
certbot
auf, die den Nginx-Startvorgang certbot
, bis die vom certbot
Container erstellten SSL-Konfigurationsdateien certbot
. Ohne dies würde Nginx den Start verweigern. - Zeile 30 erstellt einen Hintergrundprozess, der regelmäßig alle zehn Sekunden das Vorhandensein einer Flag-Datei mit dem Namen
.nginx-reload
überprüft und Nginx anweist, die Konfiguration neu zu .nginx-reload
, sobald sie .nginx-reload
. Diese Datei erstellt auch certbot, wenn das Zertifikat aktualisiert wird. - Zeile 34 startet Nginx im normalen Modus. In diesem Fall bedeutet
exec
, dass der aktuelle Shell-Prozess durch den Nginx-Prozess ersetzt wird.
Eine weitere wichtige Datei in diesem Bild ist die Konfiguration des virtuellen Commento-Servers, die Nginx dazu zwingt, HTTPS-Anforderungen an den commento
weiterzuleiten:
server { listen [::]:443 ssl ipv6only=on; listen 443 ssl; server_tokens off; root /var/www/html; index index.html index.htm index.nginx-debian.html; server_name __DOMAIN__; location / { proxy_pass http://app:8080/; proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } ssl_certificate /etc/letsencrypt/live/__DOMAIN__/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/__DOMAIN__/privkey.pem; include /etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; } server { listen 80 default_server; listen [::]:80 default_server; server_tokens off; server_name __DOMAIN__; location /.well-known/acme-challenge/ { root /var/www/certbot; }
Der erste Serverblock (Zeilen 1-21 ) beschreibt die Arbeit mit HTTPS und der Weiterleitungsregel. Hier werden Let's Encrypt-Zertifikatdateien erwähnt (oder stattdessen verwendete Stubs).
Die vom Server bereitgestellte Domäne wird beim Erstellen des Images als Argument übergeben. Es ersetzt die Zeile __DOMAIN__
in der Serverkonfiguration.
Der zweite Block (Zeilen 23-38 ) ist die Konfiguration des HTTP-Servers, der vom Certbot zur Bestätigung des Domänenbesitzes verwendet wird (die sogenannte „ACME-Herausforderung“). Alle anderen Anfragen bewirken eine Umleitung über HTTPS an die entsprechende Adresse.
certbot
Unser Certbot-Image basiert auf dem offiziellen Build mit dem folgenden Skript:
Ein kurzer Überblick über seine Linien:
- Zeile 3 ist wie im vorherigen Skript für die regelmäßige Fertigstellung des Containers erforderlich.
- Die Zeilen 17-19 überprüfen die erforderlichen Variablen.
- Und in den Zeilen 22-25 - dass die Verzeichnisse, die für das Funktionieren von certbot erforderlich sind, korrekt bereitgestellt werden.
- Die Gabel folgt:
- Die Zeilen 30-50 werden nur beim ersten Start des Containers ausgeführt:
- Ein Dummy-Zertifikat wird kopiert, sodass Nginx normal gestartet werden kann.
- Nginx wartet unterdessen auf das Ende dieses Prozesses, wonach der Download fortgesetzt wird.
- Nach dem Start von Nginx leitet certbot den Prozess zum Abrufen eines gültigen Zertifikats von Let's Encrypt ein.
- Und schließlich wird, sobald das Zertifikat empfangen wurde, die
.nginx-reload
Datei erstellt, was Nginx darauf hinweist, dass es Zeit ist, die Konfiguration neu zu laden.
- Zeile 54 wartet auf den Start von Nginx - falls bereits ein vollständiges Zertifikat verfügbar ist.
- Nach all dem (Zeilen 58-63 ) fährt er alle 12 Stunden mit dem Zyklus fort, überprüft die Notwendigkeit, das Zertifikat zu erneuern, und signalisiert Nginx den Neustart.
Die postgres
und postgres
Container verwenden die von den Entwicklern bereitgestellten Originalbilder ohne Änderungen.
Systemd Service
Das letzte Teil dieses Puzzles ist die systemd commento.service
Einheitendatei , für die Sie in /etc/systemd/system/commento.service
einen Symlink /etc/systemd/system/commento.service
damit sie zu einem guten Zeitpunkt beim Systemstart /etc/systemd/system/commento.service
:
[Unit] Description=Commento server [Service] TimeoutStopSec=30 WorkingDirectory=/opt/commento ExecStartPre=-/usr/bin/docker volume create commento_postgres_volume ExecStartPre=-/usr/bin/docker volume create certbot_etc_volume ExecStartPre=-/usr/local/bin/docker-compose -p commento down -v ExecStart=/usr/local/bin/docker-compose -p commento up --abort-on-container-exit ExecStop=/usr/local/bin/docker-compose -p commento down -v [Install] WantedBy=multi-user.target
Zeilen:
- Zeile 6 impliziert, dass der Projektcode in das Verzeichnis
/opt/commento
geklont wird - dies ist viel einfacher. - In den Zeilen 7 bis 8 werden externe Volumes erstellt, sofern dies noch nicht geschehen ist.
- In Zeile 9 werden die möglichen Reste der vorherigen Container gelöscht. Externe Volumes bleiben erhalten.
- Zeile 10 markiert den tatsächlichen Start von Docker Compose. Das
--abort-on-container-exit
gesamte Herde von Containern, wenn einer von ihnen --abort-on-container-exit
. Dank dessen wird systemd zumindest bewusst sein, dass der Dienst gestoppt wird. - In Zeile 11 werden erneut Container, Netzwerke und Volumes bereinigt und gelöscht.
Quellcode
Eine voll funktionsfähige Implementierung, die nur die Konfiguration von Variablen in docker-compose.yml
, ist auf GitHub verfügbar. Sie müssen nur die in README beschriebenen Schritte sorgfältig ausführen .
Der Code unterliegt der MIT-Lizenz .
Vielen Dank für das Lesen zu diesem Ort, Kommentare sind herzlich willkommen!