Statische Kommentare in Jekyll mit eigener Instanz von Staticman
Eine Kommentar-Funktion mit Hilfe einer eigenen Instanz der Staticman-App auf Heroku gehostet in einer Webseite realisieren, die mit einem statischen Webseiten-Generator wie Jekyll gebaut ist.
Einführung
Mit Staticman läßt sich in Webseiten, die von statischen Generatoren wie Jekyll gebaut werden, eine Kommentarfunktion umsetzen umsetzen. Staticman ist eine NodeJS Applikation, die benutzergenerierten Inhalt von der Webseite durch z.B. ein Formular erhält und sie als Datendateien zu Github (oder Gitlab) hochlädt.
Eduardo Bouças, der Entwickler von Staticman, stellte dazu seine App öffentlich zur Verfügung. Wegen der zunehmenden Beliebtheit von statischen Webseiten-Generatoren und weil man nicht auf Kommentare verzichten wollte, stößt die App jetzt leider regelmäßig an ihre Quota-Grenzen und ist nicht mehr gut nutzbar.
Da die App Open Source ist, ist der einfachste Weg, die App selbst zu hosten. Zum Hosten besorgt man sich einen kostenlosen Account auf Heroku, erstellt sich einen Fork von Staticman und veröffentlicht diesen auf Heroku. Doch dazu jetzt im einzelnen.
Staticman Fork auf Github
Als erstes erstellte ich mir einen neuen Github-Account, sozusagen einen Bot-Account, der die Daten in meinen Webseiten-Repos pusht. Außerdem habe ich einen Fork des Staticman-Repos hier abgelegt. Das beides hängt sonst nicht zusammen. Man kann auch das Staticman-Repos nach local klonen und von dort dann zum App-Hoster pushen. Wenn man jedoch den Heroku-Account mit dem Bot-Account verbindet, kann man auch automatisch bei Push ins Bot-Github-Repos nach Heroku deployen.
Warum der Bot-Account? Damit die vom Kommentarformular geposteten Daten und von der Staticman-App daraus gebauten Datendateien in unserer Webseiten-Repository gepusht werden können, muß das neue Bot-Github-Repos Schreibrechte auf das Webseiten-Repos erhalten. Sollte der neue Bot-Account einmal kompromittiert werden, ist nur der Bot-Account verloren und nicht der Account, in dem all meine Repositories wohnen.
In den Account-Settings des Bot-Accounts in die Developer Settings gehen und einen Personal Access Token erstellen. Ich habe diesen mit allen Rechten bei repo und bei admin:repo_hook erstellt. Zweiteres ist für das automatische Deployment zu Heroku. Den Key sofort kopieren und sicher wegspeichern, da er nur dieses eine mal angezeigt wird.
Dann einen Fork des Staticman-Repos in diesen Bot-Account erstellen und zum Bearbeiten das Repos lokal klonen.
Konfiguration der Staticman-App
Wie man den Artikeln hier1 und hier2 entnehmen kann (die restlichen Quellen3,4,5), funktioniert der aktulle Master-Branch von Staticman nicht wie erwartet. Der in diesen Artikeln erwähnte Commit 55d1430 funktioniert jedoch. Daher erstellen wir daraus einen Branch und arbeiten damit:
$ git checkout -b production 55d1430
Zur Konfiguration der App müssen wir der App einige Daten mitgeben, wie z.B. den Personal Access Token unseres Bot-Accounts. Damit dieser aber nicht im Klartext in unserem Repos liegt, erstellen wir die Konfigurationsdatei mit Platzhaltern. Die echten Werte kann man dann per heroku cli
übertragen oder im Admin von Heroku in den Einstellungen der App hinterlegen. Als erstes die Datei config.production.json
als Kopie der Datei config.sample.json
erstellen.
$ cp config.sample.json config.production.json
Dann den Inhalt der config.production.json
so abändern
{
"githubToken": process.env.GITHUB_TOKEN,
"rsaPrivateKey": JSON.stringify(process.env.RSA_PRIVATE_KEY)
}
Diese Konfigurationsdatei dann zur gitignore so hinzufügen, das sie auf jeden Fall von Git beachtet wird. Konfigurationsdateien werden von der gitignore eigentlich nicht beachtet. Dazu
$ echo "!config.production.json" >> .gitignore
ausführen.
Zum Schluß wird noch eine Datei namens Procfile
erstellt, die dazu dient, daß die App nach einem Deploy automatisch gestart wird.
web: npm start
Alle Änderungen werden dann dem Repos hinzugefügt.
$ git add config.production.json Procfile .gitignore
$ git commit -m "Set up Staticman v3 for deployment to Heroku"
In den Settings des Webseiten-Repos bei Github dann noch den Bot-Account als Collaborator eintragen und den Einladungslink kopieren. Dann aus diesem Account ausloggen und in den Bot-Account einloggen und den Einladungslink im Browser aufrufen. Nach der Bestätigung kann der Bot-Account bei Github auch in das Webseiten-Repos schreiben. Und pushen, was dafür nötig ist, daß die Posts in der Webseite erscheinen.
Heroku
In Heroku erstellt man sich einen kostenlosen Account und legt eine App an. In der App kann man unter dem Menlüpunkt Deploy als Deploymethode Github auswählen. Ist man in Github in seinem Bot-Account eingeloggt, wählt man das Repos mit dem Staticman-Fork aus und als Branch den vorher angelegten production-Branch. Aktiviert man dann noch die automatischen Deploys wird bei jedem Push in das Staticman-Repos ein Deployment nach Heroku durchgeführt, die App neu gebaut und gestartet. Unter https://HEROKU_APP_NAME.herokuapp.com sollte dann ein Hello from Staticman version 3.0.0! erscheinen, womit man weiß, daß die App läuft.
Heroku App Settings
In der App unter Settings den Button Reveal Config Vars
klicken. Hier müssen 3 Parameter gesetzt werden.
GITHUB_TOKEN
: Als Wert den oben im Github-Bot-Account angelegten (und hoffentlich abgespeicherten) Personal Access Token eingeben.NODE_ENV
: Hierproduction
als Wert eintragen.RSA_PRIVATE_KEY
: Hier müssen wir einen Verschlüsselungsschlüssel erstellen, mit dessen Hilfe die App bestimmte sensible Daten ver- und entschlüsselt.
Diesen Key erstellt man einfach an der lokalen Konsole mit dem Befehl
openssl genrsa -out staticman-key.pem
Diesen Key mit einem Text-Editor öffnen und alle Zeilenümbrüche entfernen, so daß der gesamte Inhalt in einer Zeile steht. Diesen String dann als Wert eintragen.
Heroku Endpoints
Zur Arbeit mit der App benötigen wir zwei Endpoints, also URLs, unter der wir Funktionen der App aufrufen können.
Das ist einmal die Verschlüsselungsfunktion unter https://HEROKU_APP_NAME.herokuapp.com/v3/encrypt/STRING_TO_ENCRYPT. Damit werden folgende Werte in der staticman.yml verschlüsselt:
- notifications.apiKey und notifications.domain
- reCaptcha.secret
Nicht vergessen, den Wert für reCaptcha.secret auch in der config.yml zu hinterlegen.
Der zweite Endpoint ist der eigentliche Endpoint, den wir im Formular als Action hinterlegen. Er lautet
Anpassung der Staticman-App
Bei der Verwendung der App fielen mir zwei Dinge auf. Einmal gibt es beim Bauen der App Warnings in den Heroku-Logs, das bestimmte Informationen nicht im Schema der App enthalten sind. Es fehlen: allowedOrigins, endpoint und die notifications.fromAddress. Im Webseiten-Repos in der staticman.yml steht, das die hier angegebe notifications.fromAddress die in der App hinterlegte fromAddress überschreibt. Meine Tests haben ergeben, daß sie nicht überschrieben wird. Im Code der App – auch nicht im aktuellen master-Branch – habe ich das jedoch nicht gefunden. Daher habe ich das in meinem Fork implementiert. Beide Änderungen sind hier zu finden.
Mailgun
Damit man über die Kommentare und Antworten auf Kommentare benachrichtigt wird, kann man sich einen freien Mailgun-Account besorgen. Der Api-Key und die Mail-Domain wird dann verschlüsselt wie oben beschrieben in die staticman.yml eingetragen.
Schlußbemerkung
Mit Hilfe dieser Services hat man eine Kommentarfunktion mit Email-Benachrichtigung in die statischen Webseite eingebaut. Viel Spaß beim Kommentieren!
Quellen
Diese Artikel haben mir bei der Umsetzung sehr geholfen. Danke!