- Sa 11 Januar 2020
- blog
- Martine S. Lenders
- #pelican, #administration
Da mir ja bereits ein Artikel für dieses Jahr fehlt, dachte ich mir − auch zur Eigendokumentation − gleich einen nachzusetzen nach der Einführung. In diesem Artikel dokumentiere ich, wie ich diesen Blog aufgesetzt habe.
Vorüberlegungen
Blogging-Software
Für die Generierung des Blogs entschied ich mich Pelican zu verwenden. Im Gegensatz zu Lösungen wie Wordpress oder MediaWiki, die Ihre Webseiten dynamisch generieren − also beim Aufruf der Seite, basierend auf Design-Vorlagen und in Datenbanken hinterlegten Inhalten − generiert Pelican statische HTML-Dateien, die von mir beim Webserver hinterlegt und dann vom Leser abgerufen werden können. Dies nennt man einen statischen Webseiten-Generator. Der Nachteil ist, dass dadurch Inhalte nicht direkt auf der Webseite bearbeitet werden können, sondern nur durch eine erneute Generierung der Webseiten. Daraus ergibt sich allerdings der Vorteil, dass die Webseite keine Benutzerverwaltung − also Logins − benötigt, um Unbefugte am Bearbeiten der Webseite zu hindern. Somit ist die Webseite unbedenklich unter der Datenschutzgrundverordnung.
Die andere Alternative zu einem statischen Webseiten-Generator wäre natürlich die HTML-Dateien direkt zu schreiben. Dies ist aber mit Mehraufwand verbunden, da jegliche Art von Meta-Informationen und Layoutentscheidungen für die Darstellung des Textes im Browser für jede HTML-Datei einzeln bearbeitet werden müssen. Dies wird dann besonders nervig, wenn man etwas am Design später ändern möchte, da jede HTML-Datei zu einem Artikel nochmal angefasst werden muss. Ich bevorzuge es jedoch Artikel lokal auf meinem Rechner in mir bekannten Formaten wie Markdown oder reStructuredText zu schreiben, die sich rein auf die Textstruktur und nicht das Layout des Texts konzentrieren. Pelican erlaubt mir mit Hilfe von Kommandozeeilenbefehlen diese Dateiformate in HTML überzuführen.
Zu guter Letzt ermöglicht mir Pelican auch Artikel offline zu verfassen (es sind ja nur Textdateien auf meinem Rechner), was ja auch in unserer modernen Welt mal der Fall sein kann (hallo, Deutsche Bahn ;-)). Die Ausrede „hab kein Netz, kann also nicht schreiben“ zieht also nicht.
Hosting
Die HTML-Dateien müssen natürlich bei einem Webserver liegen, damit ihr sie lesen könnt. Als Hostinganbieter dafür verwende ich seit Jahren bereits Uberspace.de. Somit war klar, dass ich auch dort meinen Blog aufsetzen werde. Da Uberspace von Haus aus Unterstützung für die Programmiersprache Python mitbringt, sollte es ein Leichtes sein das Python-basierte Pelican dort aufzusetzen.
Datentransfer
Da ich ja wie gesagt die Artikel nicht auf der Webseite selbst schreibe, brauche ich eine Möglichkeit die geschriebenen Artikel von meinem lokalen Rechner auf den Uberspace-Host zu kopieren. Dazu ist Git für mich persönlich die beste Lösung. Git ist ein unter Softwareentwicklern sehr beliebtes dezentrales Tool zur Versions- und Inhaltsverwaltung, mit dem ich langjährige Erfahrung habe. GitHub ist ein bekannter Hoster für Git-Repositories. Für mich persönlich bietet Git den maximalen Komfort in Sachen Workflow und eine niedrige Einstiegshürde um „mal eben“ einen Artikel zu schreiben.
Schritt 1: Ein Git-Repository anlegen
Glücklicherweise, hatte ich bereits vor Jahren auf meinem Uberspace-Host eine
Gitolite-Instanz aufgesetzt. Gitolite ist ein Tool um Git-Repositories − also
das Verzeichnis in dem Git Inhalte verwaltet − mit Git selbst zu verwalten.
Uberspace selbst bietet eine Anleitung an wie man Gitolite
dort einrichten kann. Somit musste ich mich nur noch um die Erstellung eines
Repositories kümmern, indem ich Gitolite entsprechend konfigurierte. Dazu
erweiterte ich conf/gitolite.conf
im gitolite-admin
-Repository mit den
folgenden Zeilen erweitern:
repo blog.martine-lenders.eu
RW+ = myuser
Diese Konfiguration erstellt ein Repository namens blog.martine-lenders.eu
und
der Benutzer myuser
bekommt Lese- und Schreibrechte (oder genauer, wem auch
immer Zugriff auf den privaten Schlüssel zum passenden öffentlichen Schlüssel
keys/myuser.pub
hat bekommt die Rechte; mehr Details findet Ihr bei
Wikipedia).
Das Ganze habe ich dann zur Versionskontrolle des gitolite-admin
-Repositorys
hinzugefügt:
git add conf/gitolite.conf
git commit -m "Add blog repository"
und zum Uberspace hochgeladen
git push
Dies führte dann dazu, dass das Repository blog.martine-lenders.eu
auf dem
Uberspace host erstellt wurde.
Schritt 2: Pelican installieren
Um Pelican auf dem Uberspace-Host zu installieren, musste ich mich erstmal in eine Kommandozeileninstanz auf dem Host einloggen:
ssh myuser@example.uberspace.de
Auf meinem Uberspace läuft CentOS 6, wo Python 3.4 die Standardversion für
Python 3 ist. Ich wollte für Pelican jedoch auch Markdown support betreiben. Die
aktuellste Version von Python's Markdown-Bibliothek
unterstützt jedoch Python 3.4 nicht mehr. Ich befürchtete zunächst das dies
Probleme bereiten könnte. Das tat es aber nicht, da auf der Maschine auch Python
3.7 installiert ist. Alles was zum Benutzen dieser Pythonversion getan werden
muss, ist python3.7
statt python3
aufzurufen.
Wenn es um Python-Software in Produktion geht, bevorzuge ich es eine dedizierte Virtualenv laufen zu lassen. Somit komme ich mit anderen Python-Programmen die auf der Maschine laufen nicht in die Quere. Virtualenv ist auf Uberspace vorinstalliert, somit musste ich nur eine Instanz erzeugen und aktivieren:
virtualenv -p python3.7 blog-env
source blog-env/bin/activate
Jetzt konnte ich endlich Pelican mit Markdown-Support installieren mithilfe von PIP installieren:
pip install pelican[Markdown]
Nun musste ich nur noch Gitolite beibringen, dass wenn ich Inhalte zum
blog.martine-lenders.eu
-Repository kopiere, diese auch veröffentlicht werden.
Ich richtete mich hierbei nach einer Anleitung meines
früheren Kommilitonen Alex. Sein Ansatz basiert darauf, dass Pelican nach einem
git push
automatisch den Blog mit einem post-receive
Hook
neugeneriert. Hooks sind Scripte (also kleine Programme), die bei bestimmten
Git-Ereignissen ausgeführt werden. Der post-receive
Hook wird also nachdem
(post) das Git-Repository etwas empfangen hat (receive) ausgeführt. In
diesem Fall ist der Hook in der UNIX-Shell-Scriptsprache geschrieben.
Durch die neuere Pelican-Version, der leicht anderen Umgebung auf Uberspace und
dem Fakt, dass ich Themes optional als sogenannte
Git-Submodules einbinden wollte, einen hatte ich einen etwas
anderen post-receive
Hook als Alex in seiner Anleitung:
#!/bin/sh
# Set created files to be readable only for user and group
umask 0022
# Get pelican configuration of repository
TARGET_DIR="$(git config --get pelican.targetdir)"
SETTINGS="$(git config --get pelican.settingsfile)"
# check for required settings, if not finish silently
[ -n "${TARGET_DIR}" -o -n "${SETTINGS}" ] || exit 0
# create temporary directory
TMP_DIR="$(mktemp -d)"
# Copy repository including submodules into temporary directory
git clone --recursive --depth=1 file://${PWD} "${TMP_DIR}"
# If copying repository was successful
if [ $? -eq 0 ]; then
# Activate Virtualenv
source ~/blog-env/bin/activate
# Generate output files to target directory
echo "Generating blog: pelican -d -o \"${TARGET_DIR}\" -s \"${SETTINGS}\""
pelican -d -o "${TARGET_DIR}" -s "${TMP_DIR}/${SETTINGS}" && \
# and if an `.htaccess` file exists
if [ -f ${TMP_DIR}/.htaccess ]; then
# copy it to the target directory as well
echo "Copying .htaccess: cp .htaccess ${TARGET_DIR}"
cp ${TMP_DIR}/.htaccess ${TARGET_DIR}
fi
fi
# remove temporary directory
rm -rf "${TMP_DIR}"
Die .htaccess
-Datei dient dem Erzwingen von HTTPS.
Die Gitolite-Konfiguration von oben musste ich entsprechend auch um die
pelican
-Konfigurationsparameter erweitern, die der Hook erwartet:
repo blog.martine-lenders.eu
RW+ = myuser
config pelican.targetdir = /var/www/virtual/myuser/blog.martine-lenders.eu/
config pelican.settingsfile = pelicanconf.py
Schritt 3: Den Blog erstellen
Jetzt musste ich noch auf meinem lokalen Rechner alles zum Schreiben einrichten. Dazu habe ich mir zunächst das − noch leere − Git-Repository geklont; also auf meinen Rechner heruntergeladen:
git clone myuser@example.uberspace.de:blog.martine-lenders.eu.git
cd blog.martine-lenders.eu
Dem Repository habe ich dann erstmal eine .gitignore
hinzugefügt, die so
aussah:
*~
.*.swp
*env/
__pycache__/
output/
Alle Dateien, die in dieser Datei gelistet werden, werden von der
Versionskontrolle ignoriert. *
steht in dem Fall für eine beliebige Folge von
Zeichen. Sollte ich sie dennoch versehentlich hinzufügen gibt es eine
entsprechende Fehlermeldung. Die .gitignore
muss natürlich zur
Versionskontrolle hinzugefügt werden
git add .gitignore
git commit -m "Add .gitignore"
Dann habe ich mir auch lokal eine Virtualenv aufgesetzt und aktiviert:
virtualenv -p python3 env
source env/bin/activate
pip install pelican[Markdown]
Die lokalen Dateien die ich zum Betreiben des Blogs benötige, hatte ich dann
einfach mit dem Befehl pelican-quickstart
, gemäß der Pelican-Dokumentation
erstellt. Auch diese wurden zur Versionskontrolle hinzugefügt:
pelican-quickstart
git add *
git commit -m "Initial import of pelican files"
Nach längerem Suchen fand ich ein Gestaltungsthema für Pelican, dass mir gefiel: Pelican Alchemy. Dieses fügte ich meinem Blog-Repository dann als Submodule hinzu:
mkdir themes
git submodule add https://github.com/nairobilug/pelican-alchemy.git themes/pelican-alchemy
git commit -m "Import pelican-alchemy theme"
und konfigurierte Pelican der Anleitung entsprechend.
Danach konfigurierte ich Pelican noch weiter nach meinem Geschmack. Hier ist die
fertige pelicanconf.py
:
#!/usr/bin/env python
# -*- coding: utf-8 -*- #
from __future__ import unicode_literals
# Meta-information about the site
AUTHOR = 'Martine S. Lenders'
SITENAME = "Kaffee mit Miri"
SITEURL = 'https://blog.martine-lenders.eu'
SITEIMAGE = '/images/profile.jpg width=160 height=160 title="Bild-Copyright: Tina Proske"'
TIMEZONE = 'Europe/Berlin'
DEFAULT_LANG = 'de'
# Build parameters
PATH = 'content'
THEME = 'themes/pelican-alchemy/alchemy'
# Feed configuration
FEED_ALL_ATOM = 'feeds/all.atom.xml'
FEED_ALL_RSS = 'feeds/all.xml'
# no other feeds
CATEGORY_FEED_ATOM = None
CATEGORY_FEED_RSS = None
AUTHOR_FEED_RSS = None
AUTHOR_FEED_ATOM = None
RSS_FEED_SUMMARY_ONLY = True
# Blogroll
LINKS = []
# Social widget (see https://fontawesome.com/icons?from=io v4.7.0)
ICONS= (('github', 'https://github.com/miri64'),
('twitter', 'https://twitter.com/miri_64'),
('instagram', 'https://www.instagram.com/miri64__/'),
('cloud', 'https://box.martine-lenders.eu/apps/social/@miri64/'),)
DEFAULT_PAGINATION = 20
DEFAULT_METADATA = {
# https://docs.getpelican.com/en/stable/content.html#publishing-drafts
'status': 'draft'
}
# Code blocks configuration
PYGMENTS_STYLE = "friendly"
PYGMENTS_RST_OPTIONS = {'linenos': 'table'}
Diese Änderungen mussten natürlich auch der Versionskontrolle hinzugefügt werden
git add pelicanconf.py
git commit -m "Configure pelican"
Schritt 4: Anfangen zu Schreiben
Nun muss ich bloß noch Anfangen einen Artikel zu Schreiben. Dies mache ich,
indem ich eine Markdown-, reStructuredText-, oder HTML-Datei im Verzeichnis
content/
erstelle und mit einem Texteditor (in meinem Fall vim aber es geht
natürlich auch mit z.B. dem Texteditor in Windows) mit Text befülle:
vim content/pelican.md
Damit der Artikel auch auf der Hauptseite erscheint und nicht als Entwurf veröffentlicht ist, muss der Status in den Metadaten der Textdatei auf „published“ gesetzt ist. Jetzt kann ich das Ganze mit Git veröffentlichen:
git add content/pelican.md
git commit -m "Publish article about setting up pelican"
git push
Der Quelltext für diese Seite sieht übrigens so aus.
Zusammenfassung
Insgesamt habe ich für das Aufsetzen etwa eine Stunde gebraucht. Es hat in der
Tat länger gebraucht, diesen Artikel zu schreiben ^^". Doch nun ist alles, was
ich zum Veröffentlichen tun muss ein simples git push
.