Als ein Argument meiner WordPress.com Migration habe ich aufgeführt, dass ich gern die Sachen “parat” habe, was für meine Blogs bedeutet, dass ich den Quellcode und die Uploads gern als lokale Kopie vorliegen habe. Zum einen ist das nützlich für lokale Entwicklungen und zum anderen dient es dem Backup.

Natürlich kann ich mich dafür händisch z.B. per FileZilla auf den FTP verbinden, aber da es nur ein gelegentlicher Prozess ist, besteht die Gefahr dabei etwas vergessen und so habe ich mich nach einer Lösung mit etwas mehr Automatisierung umgeschaut, die ich einmal einrichte und dann bei Bedarf einfach ausführen kann.

Außerdem wollte ich schon länger mal etwas mit Makefiles machen. Da bot es sich an das gleich mal zu verbinden.

Was ist das richtige Download-Tool?

Die erste Frage war, welches Tool ich für die Verbindung zum FTP nutzen sollte. Hier gibt es einige mögliche Ansätze, manche davon sind überraschend. So ist es zum Beispiel möglich FileZilla per Kommandozeile fernzusteuern, allerdings ist der entscheidende Parameter zum Download nur unter Windows vorhanden.

Meine nächste Idee war, ob sowas nicht einfach per rsync möglich ist. Ich nutze rsync schon für einige andere Backup-Aufgaben, da liegt dieser Weg eigentlich nahe. Leider kann rsync nicht ohne weiteres mit FTP-Servern umgehen. Es gibt grundsätzlich die Möglichkeit über curlftpfs den FTP-Server zu mounten, aber diesen Weg hab ich nicht weiter verfolgt, erschien er mir doch eher umständlich für die ansich recht einfache Anforderung eines kompletten Downloads einen Verzeichnisses.

Mit curl als Tool selbst kann sich man ebenfalls zu einem FTP verbinden, allerdings bringt curl keine Option mit rekursiv Ordner herunterzuladen. Das ist daher auch eher unpraktisch für meine Zwecke. So bin ich letztlich bei wget gelandet.

FTP-Download über wget

Bisher kannte ich wget in erster Linie als Tool um von der Kommandozeile aus Dateien “mal eben” herunterzuladen. Ich wusste auch, dass es die Fähigkeit hat komplette HTML-Seiten mit allen Bildern herunterzuladen. Dass das Ganze auch für FTP-Server genutzt werden kann, war mir dagegen neu.

Die Syntax ist dabei im Grunde recht simpel:

wget --ftp-user=XXX --ftp-password=XXX ftp://gruniversal.de/

Wichtig ist hierbei --ftp-user und --ftp-password statt der Variante ohne --ftp zu nutzen, da sich wget sonst per HTTP zum Server verbindet.

Für einen rekursiven Download gibt man zusätzlich --recursive an. Standardmäßig steigt wget dabei bis zu fünf Ebenen herab, was für meine Zwecke definitiv nicht ausreicht, daher hab ich das Limit mit --level=99 deutlich erhöht.

Außerdem fand ich die Ausgabe relativ hektisch, was man mit --no-verbose auf ein sinnvolles Maß begrenzen kann. In meinen Fall hab ich außerdem noch --no-host-directories angegeben, damit kein extra Verzeichnis für den Servernamen angelegt wird, sondern nur das gewünschte Verzeichnis geladen wird.

Mein vollständiger Aufruf sieht damit in etwa so aus:

wget --ftp-user=XXX --ftp-password=XXX \
--recursive --level=99 --no-host-directories --no-verbose \
ftp://server.provider.de/blog.gruniversal.de/

Ein Makefile für mehr Komfort

Um sich das nicht merken und nicht immer von Hand eingeben zu müssen, macht es Sinn diesen Aufruf in eine Datei zu packen. Traditionell hab ich dafür dann ein bash-Script geschrieben, aber diesmal kommt make (genauer GNU Make) zum Einsatz.

Eine Installation ist vermutlich nicht erforderlich, weil das Tool standardmäßig für viele Anwendungen erforderlich ist (notfalls: apt-get install make).

Um make zu nutzen, erstellt man ein makefile an und legt darin ein oder mehrere sogenannte “Rezepte” an. Innerhalb eines Rezeptes können mehrere Aufrufe stehen, die um ein Tab eingerückt sind. In meinem Fall also in etwa so:

download-blog:
	wget --ftp-user=XXX --ftp-password=XXX \
	--recursive --level=99 --no-host-directories --no-verbose \
	ftp://server.provider.de/blog.gruniversal.de/

Die Anwendung erfolgt dann einfach über die Kommandozeile, wobei die Bash das makefile erkennt und per Tab eine Autovervollständigung für die Rezepte anbietet:

david@mars ~ $ make download-
download-blog

Mit dem benannten Befehl wird nun der Ordner blog.gruniversal.de, der den Inhalten der gesamten Subdomain für den WordPress Blog entspricht heruntergeladen. Damit dabei keine Kopie angelegt wird und der alte Ordner noch erhalten bleibt, habe ich das makefile noch wie folgt erweitert:

timestamp:=$(shell date +%Y%m%d_%H%M%S)

download-blog:
	# zuerst wird das alte Verzeichnis gesichert
	mv blog.gruniversal.de "blog.gruniversal.de_$(timestamp)"

	# danach erfolgt das eigentliche Kopieren
	wget --ftp-user=XXX --ftp-password=XXX \
	--recursive --level=99 --no-host-directories --no-verbose \
	ftp://server.provider.de/blog.gruniversal.de/

Weitere Betrachtungen

Mit oben stehender Lösung kann der gewünschte automatische Download der Inhalte erreicht werden. Der Prozess arbeitet dabei relativ zügig und vergisst keine Dateien und hat sogar eine einfache Form der Versionierung bekommen.

Was mich bisschen stört, ist dass das Passwort zum Server im Klartext im makefile steht. Abhilfe schafft hier die Option --ask-password oder die Auslagerung des wget-Passworts in eine separate Datei.

Nachteilig ist, dass tatsächlich immer der gesamte Ordner heruntergeladen wird, auch wenn ggf. nur kleine Änderungen erfolgt sind. Hier wäre eine Synchronisation besser geeignet als das stumpfe Herunterladen. Dies würde Zeit und Traffic einsparen.

Da ich den Prozess im Moment nur gelegentlich ausführe und er nur ca. 15 Minuten läuft, kann ich damit aktuell leben. Es wäre aber ggf. eine interessante Erweiterung, die allerdings dann vrsl. nicht mehr durch wget leistbar wäre.

Bei der Recherche hab ich von Tools wie lftp, ncftp oder csync gelesen, die dafür ggf. in Frage kommen, von mir aber nicht weiter untersucht wurden. Vielleicht schau ich mir das nochmal genauer an und dann lest ihr hier davon.

Was außerdem noch fehlt, ist eine Möglichkeit auch die Datenbank des WordPress Blogs herunter zu laden. Vorerst nutze ich dafür das Plesk-Interface beim Provider. Schicker wäre natürlich das auch über das makefile zu machen. Mal schauen :)