Als kleine Dokumentation für mich und weil mich ab und zu doch auch andere Menschen fragen, wie ich eigentlich meine Ghost-Instanz auf meinem Uberspace Version 6 update, möchte ich heute eine kleine Anleitung aka. How-To hier veröffentlichen.

Auch wenn es schon einige andere Anleitungen im Netz gibt, so hilft es vielleicht dem ein oder anderen trotzdem nochmal irgendwie anders weiter.

Benachrichtigung über neue Ghost-Version

Damit ich keine (größere) Version von Ghost verpasse, habe ich mir bei libraries.io eine Notification für das Ghost-Repository eingestellt:

Auf libraries.io kann man sich benachrichten lassen, sobald ein neues Release existiert. (Screenshot vom 10.01.19)

Früher habe ich die Ghost-Updates, sobald ich über ein neues Release per E-Mail benachrichtigt wurde, tatsächlich manuell gemacht. Wie das ablief, könnt ihr hier nachlesen:

Manuelles Update mittels Konsole

Wenn ihr euch auf euren Server verbunden habt, wechselt zuerst in das Verzeichnis, wo eure Ghost-Installation liegt:

cd ghost/

Ladet euch danach die neueste Version mittels wget herunter. Beispiel:

wget https://github.com/TryGhost/Ghost/releases/download/2.10.1/Ghost-2.10.1.zip

Entpackt danach die eben heruntergeladene ZIP-Datei:

unzip Ghost-2.10.1.zip

Falls ihr gefragt werdet, ob ihr bestehende Dateien überschreiben möchtet, wählt »Ja« oder »Alle«.

Als nächstes führt ihr folgenden Befehl aus, um das Update der Dateien und Abhängigkeiten anzustoßen:

npm install --python="/usr/local/bin/python2.7" --production

Initialisiert und migriert danach noch die Datenbank:

NODE_ENV=production knex-migrator init
NODE_ENV=production knex-migrator migrate

Schlussendlich wird der Ghost-Service noch neu gestartet. Wenn ihr euch an die Anleitung der Ubernauten gehalten habt, sollte dies mit folgendem Befehl möglich sein:

svc -du ~/service/ghost

Danach könnt ihr die zuerst heruntergeladene ZIP-Datei löschen:

rm Ghost-2.10.1.zip

Und ihr seid fertig!

Automatisierte Lösung mittels Update-Skript

Irgendwann bin ich auf ein Update-Skript gestoßen, was das ganze deutlich vereinfacht und sogar noch verbessert. Da ist nämlich sogar ein Backup der bestehenden Instanz inkludiert.

#!/bin/bash
#set -v
GHOSTDIR=~/ghost
PACKAGE_VERSION_OLD=$(sed -nE 's/^\s*"version": "(.*?)",$/\1/p' $GHOSTDIR/package.json)
CURRENT_GHOST=$(curl -s https://api.github.com/repos/TryGhost/Ghost/releases | grep tag_name | head -n 1 | cut -d '"' -f 4)
CURRENT_GHOST_DOWNLOAD=$(curl -s https://api.github.com/repos/TryGhost/Ghost/releases/latest | grep browser_download_url | cut -d '"' -f 4)
CURRENT_GHOST_FILE=$(echo $CURRENT_GHOST_DOWNLOAD | sed 's:.*/::')
echo "Installierte Version von Ghost: $PACKAGE_VERSION_OLD"
echo " Verfuegbare Version von Ghost: $CURRENT_GHOST"
cd $GHOSTDIR
if [[ $CURRENT_GHOST != $PACKAGE_VERSION_OLD ]]
then
	read -r -p "Soll Ghost jetzt von Version $PACKAGE_VERSION_OLD auf $CURRENT_GHOST aktualisiert werden? [J/n] " response
	if [[ $response =~ ^([jJ][aA]|[jJ]|"")$ ]]
	then
		read -r -p "Soll ein Backup der bisherigen Instanz erstellt werden? [J/n] " response
		if [[ $response =~ ^([jJ][aA]|[jJ]|"")$ ]]
		then
			echo "Backup von bisheriger Version unter $GHOSTDIR-$(date +%F@%T) wird erstellt..."
			cp -r $GHOSTDIR $GHOSTDIR-$(date +%F@%T)
		fi	
		echo "Ghost $CURRENT_GHOST wird heruntergeladen und entpackt..."
		curl -LOk $CURRENT_GHOST_DOWNLOAD
		unzip $GHOSTDIR/$CURRENT_GHOST_FILE -d ghost-latest
        cp $GHOSTDIR/core/server/config/env/config.production.json $GHOSTDIR/ghost-latest/core/server/config/env/config.production.json
		rm $GHOSTDIR/$CURRENT_GHOST_FILE
		rm -rf $GHOSTDIR/core
		rm -rf $GHOSTDIR/content/themes/casper
		rm $GHOSTDIR/index.js
		rm $GHOSTDIR/*.md
		rsync -a --remove-source-files $GHOSTDIR/ghost-latest/* $GHOSTDIR
		rm -rf $GHOSTDIR/ghost-latest
		read -r -p "Cache loeschen vor Ghost-Aktualisierung (nicht noetig ab nodejs-8)? [j/N] " response
		if [[ $response =~ ^([jJ][aA]|[jJ])$ ]]
		then
			echo "Cache wird geloescht und Ghost danach aktualisiert..."
					rm -rf $GHOSTDIR/node_modules && npm cache clean --force && npm install --python="/usr/local/bin/python2.7" --production
		else
			echo "Ghost wird jetzt aktualisiert..."
					npm install --python="/usr/local/bin/python2.7" --production
		fi
        echo "Die Datenbank von Ghost wird auf die neue Version migriert..."
		NODE_ENV=production knex-migrator migrate
		svc -du ~/service/ghost
		PACKAGE_VERSION=$(sed -nE 's/^\s*"version": "(.*?)",$/\1/p' $GHOSTDIR/package.json)
		echo "Ghost wurde von Version $PACKAGE_VERSION_OLD auf Version $PACKAGE_VERSION aktualisiert und wird neu gestartet. Dies kann ein paar Sekunden dauern..."
		echo "Bei Fehlern Logfile ueberpruefen: 'tail -F ~/service/ghost/log/main/current'"
	else
		echo "-> Ghost wird nicht aktualisiert"
	fi
else
	echo "-> Ghost ist bereits auf dem aktuellen Stand, keine Aktualisierung notwendig"
fi

Zur Verwendung gibt es nur diesen einen Hinweis zu beachten:

Einzig und allein Zeile 3 sollte angepasst werden und Ghost bereits als Dienst ghost eingerichtet sein.

Quelle: peleke.de

Ich komme mit dem Skript sehr gut zurecht: Zuerst wähle ich mich via Terminal/SSH auf den Server ein, starte das Skript mit sh update-ghost.sh, beantworte die Fragen und lasse es laufen. Das einzige, was dort nicht funktioniert, ist der automatische Neustart nach Beenden der Datenbank-Migration. Da passiert einfach nichts mehr und ich muss das Skript (auf dem Mac mit Ctrl + C) abbrechen und den Neustart des Services mit svc -du ~/service/ghost selbst vornehmen.

Alles in allem bin ich mit der Lösung sehr zufrieden und kann sie jedem empfehlen. Wie handhabt ihr das Updaten eures Ghost-Blogs, wenn die Ghost CLI bei eurem Hoster nicht läuft? Schreibt mir gern auf Twitter, solange Ghost keine eigene Kommentarfunktion hat – ich heiße dort @heartcrazed.

(Bildquelle: Markus Spiske via unsplash.com)