juergen.rocks

Alles neu macht der März: Großes Update für juergen.rocks

Neben diversen Updates an Front- und Backend-Frameworks stand auch ein Wechsel auf einen neuen Uberspace an. Entsprechend wurde die Chance genutzt, einiges grundsätzlich zu überarbeiten und Altlasten über Bord zu werfen.

Es ist vollbracht. Das Deployment ist abgeschlossen, die DNS-Einträge umgestellt. Jetzt ist kurz Zeit, auf die Entwicklung der letzten Wochen und Monate1 zurückzublicken.

Die wichtigsten Neuerungen

Hier nun die wichtigsten Dinge, die sich geändert haben. Im Optimalfall nimmt man keine besondere Notiz von den Änderungen (die meisten werkeln im Hintergrund), aber für den einen oder anderen mag das spannend sein.

Update auf Django 3.0.4

Vor dem Neu-Deployment war das Django-Framework hinter juergen.rocks auf der Version 1.11. Der Support für diese Version läuft im April 2020 aus2. Insofern war es längst Zeit für ein Upgrade.

Erfreulicherweise mussten nur die Dinge angefasst werden, für die sowieso ein Refactoring geplant war. Ich wurde von keinen großen Überraschungen heimgesucht.

Django 3.0.4 war zum Zeitpunkt des Deployments die aktuellste Version, und alle Tests liefen damit grün. Ich hoffe, dass das so bleibt bis zur Version 3.2, welche dann die nächste LTS-Version ist. Da läuft aber noch viel Wasser den Rhein hinunter.

Login zwangsweise mit 2FA

Jedem, der mich fragt (und auch jedem, der mich nicht fragt) erkläre ich fortwährend die Vorzüge der Zwei-Faktor-Authentifizierung. Aber mein eigenes Blog unterstützte bisher keinen Login mit einem zweiten Faktor. Das ist jetzt anders. Es werden TOTPs verwendet, die mit einer Handy-App erzeugt werden.

Das Backend wurde entsprechend angepasst, außerdem werden automatisch QR-Codes für die Konfiguration der Handy-App erzeugt.

Es gibt keine Recovery-Codes, aber es gibt die Möglichkeit, sich ein neues Secret erzeugen zu lassen, wenn man noch alle anderen Zugangsdaten und ein paar Extra-Infos kennt.

Umbau der Suche auf neue Basis

Die bisherige Suche suchte platt in der Datenbank. Und dort auch nur in den Blog-Posts.

Die neue Suchmaschine basiert auf Whoosh3, und hat einen Suchindex sowohl über alle Blog-Posts, als auch über alle anderen Seiten. Initial wird der Suchindex über ein Management-Command4 aufgebaut. Da sich aber Seiten und Posts immer wieder ändern und der Index stets aktuell sein soll, wird er, gesteuert über Signale5, bei jeder Änderung aktualisiert. So können auch neue Inhalte aufgenommen und depublizierte wieder entfernt werden.

Netter Beifang: Jetzt werden auch Operatoren wie AND und OR unterstützt (auch geklammert), und es kann gezielt in title: und content: gesucht werden. Standardmäßig wird im Inhalt mit AND-verknüpften Begriffen gesucht.

Die Suche ist auf jeder Seite in der Navbar verfügbar, hat aber auch eine eigene Seite: Zur Suche

Sicher könnte man irgendwann die neuen Suchmöglichkeiten dort auch mal dokumentieren...

Kommentarfunktion verbessert

Die bisherige Kommentarfunktion war so gestaltet, dass jeder einen Kommentar schreiben konnte, aber nur ich auf Kommentare direkt antworten konnte. Dazu waren Kommentare und ihre Antworten starr verknüpft. Diese Verknüpfung ist aufgehoben. Nun kann jeder auf jeden Kommentar antworten. Entsprechend werden auch die Gesprächsfäden dargestellt.

Eingeloggte Benutzer müssen zukünftig kein Captcha mehr lösen. Außerdem steht ihnen Markdown zur Gestaltung der Kommentare zur Verfügung und die Kommentare werden ohne Moderation direkt veröffentlicht. Kommentare eingeloggter Benutzer sind entsprechend gekennzeichnet.

Für nicht eingeloggte Benutzer bleibt alles beim alten: Nur Text erlaubt, alles wird komplett escaped.

Wechsel von PostgreSQL auf MariaDB

Dieser Wechsel war eigentlich nicht geplant, denn ich war und bin mit PostgreSQL sehr zufrieden.

Eigentlich ist das ein Resultat von Bequemlichkeit: Uberspace stellt MariaDB inkl. aller Management-Tools zur Verfügung. Da die Suche nun nicht mehr auf den Volltext-Features von PostgreSQL basiert, war die Umstellung lediglich ein konfigurativer Aufwand. MariaDB genügt den Anforderungen.

So muss ich mir jetzt keine Gedanken über Setup, Betrieb und Backups machen.

Weniger Cookies

Früher hat juergen.rocks drei Cookies verwendet: Einen für die Session, einen für den CSRF-Schutz und einen für die Bestätigung des EU-Cookie-Hinweises. Jetzt wird grundsätzlich nur noch ein Cookie für die Session verwendet.

Das CSRF-Token wird innerhalb der Session gehalten, genau so wie die Information über die Akzeptanz des Cookie-Hinweises.

Optional ist im Rahmen des Mehrsprachigkeitsfeatures noch ein Cookie für die gewählte Sprache denkbar, doch das wird zur Zeit noch nicht eingesetzt.

Alle Cookies sind aber so konfiguriert, dass sie maximal so lange wie die Browser-Session leben. Es gibt keine persistenten Cookies. Das bedeutet zwar auch, dass man sich bei jedem Besuch neu anmelden muss, aber für meinen Einsatzzweck ist das schon in Ordnung.

Es gab zwar noch nie Werbe-, Tracking-, oder Third-Party-Cookies bei juergen.rocks, sondern an sich nur technisch notwendige. Da nun die Zahl noch weiter eingedampft wurde, konnte der Cookie-Hinweis entsprechend angepasst werden.

So gibt es den geforderten Hinweis, aber der Benutzer erhält gleich die Information, dass er hier gut aufgehoben ist und es nichts gibt, was er erst in zig Dialogebenen abschalten müsste.

Sitemaps-Generierung mit Bordmitteln

Früher entstand die Sitemap für Suchmaschinen durch ein Management-Command mit viel schräg zusammengestöpselten XML-Krempel.

Jetzt wird die entsprechende Django-Funktionalität6 verwendet. Das ist nicht nur bedeutend komfortabler und wartbarer, sondern auch deutlich fehlerunanfälliger.

Feeds-Generierung mit Bordmitteln

Auch die Feeds wurden in der Vergangenheit über ein Management-Command gelegentlich neu erzeugt. Das übernehmen nun auch Django-Bordmittel7. Damit kann nun neben dem RSS-Feed auch ein Atom-Feed angeboten werden, ohne zusätzlichen Implementierungsaufwand.

Viele Views ohne Session und damit ohne Cookies

In der Vergangenheit wurden, bedingt durch die SessionMiddleware, alle Views zwangsweise mit Sessions versehen, und damit die Aufrufe mit Session-Cookies. Dazu kam dann noch der passende Eintrag in der Datenbank.

Nun gibt es eine Vielzahl von Views, die keinerlei Sessions benötigen, z. B. für die Sitemaps, Atom- oder RSS-Feeds. Entsprechend wurde eine Erweiterung der Standard-SessionMiddleware entwickelt, bei der man für bestimmte Views das Session-Handling abschalten kann. Jetzt werden keine unnötigen Sessions mehr eröffnet. Das führt zu weniger Last auf der Datenbank und dazu, dass ein Besucher, der nur eines dieser Views besucht, erst gar keinen Cookie bekommt.

Integration der R2NSC Wetterseite

In den Jahren 2018 und 2019 nahm ich an der Ruhr2NorthSeaChallenge, einer eintägigen Radtour von Duisburg bis nach Bensersiel an der Nordsee, teil. Für 2019 habe ich eine kleine Wettervorhersage für die Strecke gebaut.

Zwar kann ich 2020 nicht teilnehmen, aber die Wettervorhersage gibt es trotzdem. Sie wird jetzt aber nicht mehr "standalone" erzeugt, sondern lebt hier im Kontext des Blogs.

Die Integration ins juergen.rocks-Template ist noch nicht optimal, aber für's erste steht sie auch nach der Migration weiter zur Verfügung, und zwar unter dem gleichen Link, der 2019 die Runde machte: https://juergen.rocks/r2nsc-wetter/wetter.html - der Link leitet dann auf die konkrete Seite weiter.

Viele Cronjobs und Vorbereitung für Celery

Viele Aufgaben, die nicht im Kontext eines User-Zugriffs erledigt werden müssen, sind nun über Cronjobs geregelt, die Management-Commands aufrufen.

Mittelfristig soll das Handling dieser Jobs auf Celery8 umgestellt werden. Damit wird das Management etwas einfacher und basiert nicht mehr ausschließlich auf einem SSH-Login am Server. Außerdem können Jobs besser verteilt werden.

Riesiges Refactoring und massive Modularisierung

Zum Glück ist "Refactoring" ein dehnbarer Begriff, denn eigentlich ist im Code kein Stein auf dem anderen geblieben. Unter anderem ist das geschehen:

  • Alle Views sind nun Class Based Views, unter maximaler Nutzung von Django Generic Views9 und Mixins
  • Endlich saubere URL-Namespaces, die einem festen Konzept und einer festen Form folgen. Nun muss man nicht mehr ständig nachschlagen, wie denn eine URL genau benannt ist.
  • Modelle aufgeräumt und standardisiert, sowie die Feldnamen angeglichen. Eine UUID heißt jetzt überall uuid und nicht mal id oder obj_uuid oder so. Ein last_modified-Feld heißt nun überall so, nicht last_updated oder sowas.
  • Grundsätzlich verschiedene Funktionen sind modularisiert und in eigenständigen Apps, zusammen mit ihrem Modell, ihren URLs und Management-Commands. Das bringt mehr Ordnung und Übersicht.

Link-Verkürzungen werden nun direkt aus dem Admin-Bereich heraus verwaltet. Die QR-Codes werden gleich als SVG ausgeliefert, so dass sie in Druckerzeugnissen verwendet werden können.

Außerdem wurde der Session-Zwang für einen Aufruf eines Kurzlinks entfernt, so dass der schlichte Aufruf und die Weiterleitung an die Zieladresse ohne eine Session in der Datenbank und ohne einen Session-Cookie beim User auskommt.

Die bestehenden Links in der Datenbank wurden nicht portiert. Zum einen wurde das Feature kaum genutzt, da es keinen guten Admin-Bereich gab, und zum anderen sind die alten Kurzlinks seit Jahren nicht mehr geklickt worden. Die Nichtportierung ermöglichte dazu, die Kodierung der Links anzupassen und damit mehr Links mit weniger Zeichen unterbringen zu können.

Doppelte Backup-Strategie

Neben täglichen Datenbank-Backups wird nun in regelmäßigen Abständen ein datenbankagnostischer JSON-Dump erzeugt und gesichert. So können die Produktionsdaten in Testsysteme eingespielt werden, die nicht mit MariaDB arbeiten.

Für diese Funktion wird die Django-Management-Funktion "dumpdata"10 verwendet.

CSP flächendeckend und streng

Über die ganze Seite sind nun Content-Security-Policy11-Header ausgerollt, die keinerlei externe Ressourcen erlauben. Selbst Inline-Ressourcen sind nur in einem sehr begrenzten Rahmen erlaubt.

Deployment mit Git Tags

Das Code-Deployment erfolgt direkt aus Git heraus. Auf dem Release-Branch gibt es getaggte Versionen, die ausgecheckt werden. So ist in einem gewissen Rahmen auch ein Versions-Rollback schnell möglich.

Da alle Datenbankänderungen in Zukunft so erfolgen sollen, dass eine Abwärtskompatibilität gegeben ist, sollten Daten kein Problem darstellen. Bei echten "Breaking Changes" muss dann besser getestet werden 😂

Frontend aufgefrischt

Bei den vielen Veränderungen im Backend darf auch das Frontend nicht zu kurz kommen. Nur einige der vielen Änderungen:

  • Umstellung auf Bootstrap 412
  • Ersatz der Glyphicons durch Font Awesome13
  • Keine Inline-Styles und Inline-Skripte mehr
  • Viele JavaScript-Altlasten entsorgt
  • Konsolidierung der zig CSS-Dateien in ein Stylesheet, unter Zuhilfenahme der @media-Rules

Insgesamt ist das Blog nun besser auf Mobil-Geräten nutzbar. Die Reader-Ansicht wird auf allen Post-Seiten unterstützt.

Außerdem sind nun alle Frontend-Bibliotheken mit yarn14 gemanagt. Somit hängen die Bibliotheken nicht mehr im Repository und können leichter ausgetauscht und aktualisiert werden.

"Humanize" flächendeckend für Datumsangaben im Einsatz

Django unterstützt mit dem "Humanize"15 eine sehr einfach anzuwendende Möglichkeit, Datums- und Zeitangaben besser lesbar zu machen. So wird zum Beispiel aus dem heutigen Datum schlicht "heute", anstatt eines Datums.

Für Uhrzeitangaben wird "Humanize" bisher noch nicht verwendet.

Mehrsprachigkeit vorgesehen

Im Rahmen der Aktualisierung des Django-Frameworks und der Überarbeitung der Templates wurde gleich Mehrsprachigkeit vorgesehen. Ob die aber in einem rein deutschsprachigen Blog jemals zum Einsatz kommen wird, ist mehr als fraglich.

Allerdings war es eine gute Fingerübung, um mit Djangos Internationalisierungs- und Lokalisierungs-Features16 warm zu werden.

Alle Requirements haben nun Ranges

Damit zukünftige Updates der Python-Pakete etwas leichter von der Hand gehen gibt es keine starren Versionsangaben mehr in den Requirements. So wird durch regelmäßige Regressionen stets ein aktuelles Set an Versionen überprüft und kann zum Update freigegeben werden.

Normalisierung auf die Domain juergen.rocks

www.juergen.rocks, juergen.rocks, www.jürgen.rocks und jürgen.rocks führen alle zu diesem Blog. Für eine gewisse Standardisierung werden aber alle Hostnamen auf juergen.rocks normalisiert. Entsprechend gibt es möglicherweise beim Erstaufruf direkt einen permanenten Redirect.

Autor:

Themen:

Veröffentlicht:
14.03.2020 20:55

Zuletzt aktualisiert:
15.03.2020 00:12



Bisher keine Kommentare.


Copyright © 2020, juergen.rocks.