Webseite mit Hugo generieren ohne Installation
Veröffentlicht am 9. September 2023 • 6 Min. Lesezeit • 1.248 WörterWie generiert man eine statische Hugo Webseite ohne Hugo auf dem Rechner zu installieren?
Für diesen Blog habe ich mich für ein statisches Web-Projekt entschieden, d.h. die Seiten werden einmalig erstellt und dann vom Web-Server unmittelbar ausgeliefert. Um die Webseiten nun nicht alle von Hand erstellen zu müssen, gibt es sogenannte Statische-Webseiten-Generatoren
wie
Jekyll
,
Gatsby
oder das fantastische
Hugo
, das ich gewählt habe.
Statische-Webseiten-Generatoren verfügt i.Allg. über einige angenehme Eigenschaften:
Das tolle am Blog-Schreiben ist ja, dass man jederzeit ein Thema recherchieren und für einen kurzen Artikel aufbereiten kann, wann immer einem etwas Interessantes vor die Füße fällt.
Der gängige Weg ist es, Hugo auf einem Rechner lokal zu installieren und die Installation zum generieren der Seite zu verwenden. Soweit so bekannt.
Ich möchte hier einen alternativen Weg aufzeigen, der keine Installation voraussetzt, sondern auf einem Docker-Container aufsetzt, der wiederum Hugo enthält. Zum einfacheren Arbeiten werden die wesentlichen Befehle als Skripte umgesetzt, die dann den Container aufrufen.
Alle Tools sind komplett frei und OpenSource.
Ich nehme an ihr habt bereits Docker installiert. Wenn nicht gibt es da draussen gute Einführungen zum Thema Containerisierung und wie man damit am einfachsten anfängt (z.B. Docker Docs ).
Als Beispiel Projekt nehmen wir das aus meiner Sicht sehr schön gelungene Hugo Clarity Theme von Chip Zoller . Wenn ihr bereits ein Projekt habt, könnt ihr diese Schritte natürlich überspringen.
Auf einem Ubuntu-Linux-System erstellt man zunächst einen passenden Ordner und klont das Theme dorthinein. Anschließend werden die beigefügten Beispielseiten in das Template kopiert, um eine generierbare Webseite zu erhalten.
mkdir -p ~/projekte/hugo-clarity/themes
cd ~/projekte/hugo-clarity
git clone https://github.com/chipzoller/hugo-clarity.git themes/hugo-clarity
cp -r themes/hugo-clarity/exampleSite/* .
Das hier verwendete Github Projekt docker-hugo beschreibt dessen Verfasser Erlend Klakegg Bergheim selbst als “Truly minimal Docker images for Hugo with batteries included.”, also ein minimales Hugo Docker Image mit allem Drum und Dran.
Wir müssen uns aber nicht mit der Erstellung des Images beschäftigen, da man die aktuelle Version klakegg/hugo:0.111.3-ext-ubuntu
(zum Zeitpunkt der Artikelerstellung) wie gewohnt von
DockerHub
laden kann.
Bei einer lokalen Installation wäre die gängige Vorgehensweise den Hugo-Server mit den Parametern -D -E -F -w –disableFastRender im Ordner des Hugo-Projektes zu starten. Dazu müsste Hugo lokal installiert sein. Hier verwenden wir nun das Image klakegg/hugo , das nichts anderes macht, als Hugo in einem Container zur Verfügung zu stellen, aber das halt gut.
Zunächst werden einige Skripte erstellt. Derartige Helferlein pflege ich in einem Ordner ./tools
innerhalb des Hugo-Projektes (parallel zu ./config
und ./content
). Dieser enthält z.B. das Tool zum lokalen Starten des Hugo-Servers.
#!/bin/bash
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
USER_ID=$(id -u ${USER})
GROUP_ID=$(id -g ${USER})
IMAGE="klakegg/hugo:0.111.3-ext-ubuntu"
SERVER_PARAMETERS=""
PORT="1313"
POSITIONAL_ARGS=()
while [[ $# -gt 0 ]]; do
case $1 in
--dev|--development)
SERVER_PARAMETERS+="-D -E -F -w --disableFastRender "
shift # past argument
#shift # past value
;;
--prod|--production)
SERVER_PARAMETERS=" "
shift # past argument
#shift # past value
echo "Production Server"
;;
-p|--port)
PORT="$2"
shift # past argument
shift # past value
;;
-*|--*)
echo "Unknown option $1"
exit 1
;;
*)
POSITIONAL_ARGS+=("$1") # save positional arg
shift # past argument
;;
esac
done
echo "Starte Hugo Server mit: $SERVER_PARAMETERS auf Port $PORT"
docker run --rm -it\
-u ${USER_ID}:${GROUP_ID} \
-p ${PORT}:${PORT} \
-v ${DIR}/../:/src \
${IMAGE} server -p ${PORT} ${SERVER_PARAMETERS}
Vor der ersten Verwendung muss das Skript einmalig ausführbar gemacht werden
chmod +x ./tools/hugo-server.sh
Das Skript wird in einem separaten Terminal Fenster ausgeführt und startet wie gewohnt den Hugo-Server, der fortan den Hugo-Projektordner überwacht, das Projekt bei Änderungen neu generiert und über einen lokalen Web-Server zur Verfügung stellt.
Tipp
Wenn ihr auch Visual Studio Code als Editor verwendet, öffnet dort ein Terminal und startet das Skript dort. So sieht man beim Speichern sofort, wenn es beim Generieren Probleme gab.
Verwendung:
./tools/hugo-server.sh --dev # (development) startet den Server mit -D -E -F -w --disableFastRender
./tools/hugo-server.sh --prod # (production) startet den Server, zeigt keine als Draft markierten Seiten
./tools/hugo-server.sh --dev -p 1500 # (development), setzt den lokalen Port des Servers auf 1500
Gestartet, sollte die Ausgabe ähnlich dieser sein
./tools/hugo-server.sh --dev
Starte Hugo Server mit: -D -E -F -w --disableFastRender auf Port 1313
Start building sites …
hugo v0.111.3-5d4eb5154e1fed125ca8e9b5a0315c4180dab192+extended linux/amd64 BuildDate=2023-03-12T11:40:50Z VendorInfo=hugoguru
| EN | PT
-------------------+----+-----
Pages | 53 | 30
Paginator pages | 1 | 0
Non-page files | 2 | 0
Static files | 63 | 63
Processed images | 0 | 0
Aliases | 30 | 15
Sitemaps | 2 | 1
Cleaned | 0 | 0
Built in 627 ms
Watching for changes in /src/{archetypes,content,layouts,static,themes}
Watching for config changes in /src/config/_default, /src/config/_default/menus
Environment: "DEV"
Serving pages from memory
Web Server is available at http://localhost:1313/ (bind address 0.0.0.0)
Press Ctrl+C to stop
Für den Fall, dass Docker die Ausführung des Skriptes mit einem Rechte-Fehler
[…] unix /var/run/docker.sock: connect: permission denied.
quittiert, könnte es daran liegen, dass der aktuelle Benutzer nicht in der Docker-Gruppe enthalten ist.
sudo usermod -aG docker $USER
Jetzt nur noch einen lokalen Browser mit Url http://localhost:1313/
(bzw. dem angegebenen Port p
) starten und schon ist die Webseite im Browser.
Der Container und damit der Server kann im Terminal-Fenster mit CTRL+C beendet werden.
Das charmante am Hugo-Server ist, dass er im Entwicklungsmodus (--dev
) die baseURL
in config.toml
, die normalerweise auf die Domain zeigt unter der die Seite laufen soll, durch localhost:<port (default 1313)>
ersetzt. Dadurch läßt sich das Projekt erst auf dem lokalen Rechner ansehen.
Irgendwann ist der Artikel dann fertig, die richtigen Bilder am besten Ort eingebunden und die Rechtschreibung nach bestem Wissen und Gewissen geprüft. Jetzt ist es Zeit für den nächsten Schritt hin zur Veröffentlichung.
Mit dem folgenden Skript wird das Hugo-Projekt und damit dessen Webseiten generiert (bzw. publiziert im Hugo-Sprech).
#!/bin/bash
set -e
set -o pipefail
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
USER_ID=$(id -u ${USER})
GROUP_ID=$(id -g ${USER})
# Generieren des Projektes mit Hugo
IMAGE="klakegg/hugo:0.111.3-ext-ubuntu"
# Leeren des Ausgabe-Ordners
rm -rf ${DIR}/../public/*
docker run --rm -it \
-u ${USER_ID}:${GROUP_ID} \
-v ${DIR}/../:/src \
-e HUGO_ENVIRONMENT='production' \
${IMAGE}
Durch Ausführen des Skriptes wird alles Notwendige für die Webseite in ./public
generiert.
chmod +x ./tools/hugo-generieren.sh # einmalig das Skript als ausführbar markieren
./tools/hugo-generieren.sh
Bringt man den Inhalt von ./public
nun in das Wurzelverzeichnis eines Webservers, so wird dieser die gerade erstellte statische Webseite zur Verfügung stellen.
Die Kapselung des Statischen-Webseiten-Generators Hugo in einen Docker Container ermöglicht dessen Verwendung, ohne Hugo und dessen Abhängigkeiten auf dem lokalen Rechner installieren zu müssen. Somit bleibt diesem eine Installation erspart. Sie ermöglicht es aber auch auf verschiedenen Rechnern identische, generierte Seiten zu erzeugen, da die generierende Software (Hugo) gekapselt und versioniert im Docker Image enthalten ist.
Um die erzeugten statischen Webseiten “ins Netz” stellen zu können, fehlt noch ein Webserver und am besten eine Integration in ein einfach zu publizierendes Docker-Image.