Ich hatte es vor einiger Zeit schon einmal davon, dass ich mehrere Nextcloud Instanzen auf einem Server betreue – die logischerweise regelmäßig mit Updates versorgt werden müssen (https://gehirn-mag.net/nextcloud-auto-update-via-cli/). Neben Nextcloud habe ich auch einige Male WordPress am laufen. Auch hier sollten regelmäßig Updates installiert werden.

wp-cli

Um WordPress von der Konsole aus zu bedienen braucht es ein entsprechendes Werkzeug. Nur bringt WordPress selbst so etwas nicht mit – obwohl es einen sehr praktischen Helfer hierfür gibt: wp-cli. Im ersten Schritt ist diese gemäß Doku zu installieren: https://wp-cli.org/de/#installation. Damit dies unter meinem Ubuntu 20.04 funktioniert habe ich noch im Anschluss daran die Berechtigungen mit chmod 0755 /usr/local/bin/wp geändert.

Sehr nützlich kann die bash completition sein: https://wp-cli.org/de/#tab-vervollst%C3%A4ndigung. Abweichend von der Dokumentation habe ich diese für alle Systembenutzer eingerichtet:

root@gmn ~ # cd /etc/bash_completion.d/
root@gmn /etc/bash_completion.d # wget https://github.com/wp-cli/wp-cli/raw/master/utils/wp-completion.bash

Noch eine Vorbereitung habe ich zum Schluss gemacht: Bei mir liegen alle WordPress Instanzen unter /var/www/vhosts. Apache läuft wie gehabt unter der Benutzerkennung www-data. Um Erweiterungen für die wp-cli zu installieren braucht dieser Benutzer Schreibrechte im ~/.wp-cli Verzeichnis:

root@gmn ~ # cd ~www-data
root@gmn /var/www # mkdir .wp-cli
root@gmn /var/www # chown www-data .wp-cli

wp-cli Erweiterung

Eine praktische Erweiterung für wp-cli ist meiner Meinung nach das find-command: https://developer.wordpress.org/cli/commands/find/. Diese Ergänzung ist für das automatische Update kein Muss – betrachte es als Hinweis darauf, dass man Erweiterungen installieren kann und wie man das macht. Zuerst noch rasch die User-ID auf www-data via su geändert und wie gehabt im Verzeichnis /var/www begonnen:

root@gmn ~ # su -s /bin/bash -l www-data
www-data@gmn ~ # wp package install wp-cli/find-command
www-data@gmn ~ # wp find /var/www
+-----------------------------------------------------------------------+---------+-------+-------+
| version_path                                                          | version | depth | alias |
+--------------------------- -------------------------------------------+---------+-------+-------+
| /var/www/vhosts/xxxxxxxxxxxxxxxxxxxxxxxxxxxx/wp-includes/version.php  | 5.4.2   | 2     |       |
| /var/www/vhosts/xxxxxxxxxxxxxx/wp-includes/version.php                | 5.4.2   | 2     |       |
| /var/www/vhosts/xxxxxxxxxxxxxxxxx/wp-includes/version.php             | 5.4.2   | 2     |       |
| /var/www/vhosts/xxxxxxxxxxxxxxxxxxxxxx/wp-includes/version.php        | 5.4.2   | 2     |       |
| /var/www/vhosts/xxxxxxxxxxxxxxxxxxxxxxxxxxxxx/wp-includes/version.php | 5.1.1   | 2     |       |
| /var/www/vhosts/xxxxxxxxxxxxxxxxxxxxxxx/wp-includes/version.php       | 5.4     | 2     |       |
| /var/www/vhosts/xxxxxxxxxxxxxxxxx/wp-includes/version.php             | 5.3.2   | 2     |       |
| /var/www/vhosts/xxxxxxxxxxxxxxxxx/wp-includes/version.php             | 5.3.2   | 2     |       |
| /var/www/vhosts/xxxxxxxxxxxxxxxxx/wp-includes/version.php             | 5.4.2   | 2     |       |
| /var/www/vhosts/xxxxxxxxxxxxxxxxxxxxx/wp-includes/version.php         | 5.1.1   | 3     |       |
| /var/www/vhosts/xxxxxxxx/wp-includes/version.php                      | 5.5     | 2     |       |
| /var/www/vhosts/xxxxxxxxxxxxxxx/wp-includes/version.php               | 5.2.3   | 3     |       |
| /var/www/vhosts/xxxxxxxx/wp-includes/version.php                      | 5.5     | 2     |       |
| /var/www/vhosts/xxxx/wp-includes/version.php                          | 5.5     | 2     |       |
| /var/www/vhosts/xxxxxxxxxxxxxxxx/wp-includes/version.php              | 5.4.2   | 2     |       |
| /var/www/vhosts/xxxxxxxxxxx/wp-includes/version.php                   | 5.4.1   | 2     |       |
+-----------------------------------------------------------------------+---------+-------+-------+

Dies ist ein Beispiel einer Testumgebung auf der auch die ein oder andere etwas ältere WordPress Installation vorhanden ist – zum Teil in Backups liegend die gar nicht mehr durch den Webserver erreichbar wären.

WordPress Update

Etwas in der Doku von wp-cli gestöbert und alle notwendigen Befehle waren gefunden. Heraus kam ein Update-Skript analog zu dem oben bereit erwähnten Nextcloud Skript. Wer figlet nicht mag lässt es weg und nur den echo Befehl übrig. Ansonsten trägt man in der Variable $wp alle WordPress Instanzen ein. Da wie gehabt bei mir alle unter /var/ww/vhosts liegen wird der Teil vom Pfad etwas weiter unten im Skript eingefügt.

#!/bin/bash

#
# WordPress Auto-Updater - Nimmt die Arbeit raus ;-)
#

# 2020-08-xx, Gehirn-Mag.Net: Init

wp="
    test1/wordpress
    test2/wordpress
"

# Der sudo Befehl ;-)
sd="sudo -u www-data -- /usr/local/bin/wp"
for instance in $wp; do
    echo "~ ~ ~ ~~ ~ ~ ~~ ~ ~ ~~ ~ ~ ~~ ~ ~ ~~ ~ ~ ~~ ~ ~ ~"
    figlet -fsmall $(echo $instance | cut -d/ -f1)
    cd /var/www/vhosts/$instance
    pwd
    $sd plugin update --all
    $sd theme update --all
    $sd core update
    $sd language core update
done
exit 0

Und so sieht die Ausgabe aus für diese Seite:

~ ~ ~ ~~ ~ ~ ~~ ~ ~ ~~ ~ ~ ~~ ~ ~ ~~ ~ ~ ~~ ~ ~ ~
          _    _                                        _   
 __ _ ___| |_ (_)_ _ _ _ ___ _ __  __ _ __ _   _ _  ___| |_ 
/ _` / -_) ' \| | '_| ' \___| '  \/ _` / _` |_| ' \/ -_)  _|
\__, \___|_||_|_|_| |_||_|  |_|_|_\__,_\__, (_)_||_\___|\__|
|___/                                  |___/                
/var/www/vhosts/gehirn-mag.net/htdocs
Success: Plugin already updated.
Success: Theme already updated.
Success: WordPress is up to date.
Success: Translations are up to date.

Und wieder mal das Leben erleichtert. Dieses Skript dient als Beispiel wie man so etwas einbauen kann. Bei mir läuft ein Skript dieser Art nach dem Backup in einem mit den Kunden vereinbarten Wartungszeitpunkt. Das ist jetzt aber Deins 😉

Ist das die ganze Wahrheit?

Nein, natürlich nicht. Es gibt eine Sache die ist bei wp wichtig zu wissen: Es gibt kein wp plugin check-update. wp nutzt gechachte Daten um zu entscheiden ob es Updates gibt oder nicht. MIt wp plugin list kann man sich den aktuellen Stand anzeigen lassen.

Die eigentliche Prüfung auf Updates findet über den WordPress internen cron Dienst statt. Dem kann man mit wp ebenfalls in die Karten schauen: Ein wp cron event list zeigt alle Jobs an. Mit wp cron event run wp_update_plugins kann man „jetzt“ prüfen lassen ob es Updates für die Plugins gibt. Aber Achtung: Dies bedeutet nicht, dass alle Updates an der Stelle sofort gefunden werden. Mit den Themes geht das übrigens genaus: Einfach plugin durch theme ersetzen.

Und nun? Sind wir mal ehrlich: Mit dem Skript geht es darum die Updates nicht zu vergessen. Und das tut es. Nur nicht unbedingt in der Zeit die man selbst bräuchte wenn man regelmäßig nachsehen würde. Und da liegt das Problem: Bei vielen Instanzen hat man auch gar nicht die Zeit alle Plattformen regelmäßig zu kontrollieren. Allerdings sollte man Updates, vor allem wenn sicherheitskritisch, zeitnah einspielen. Ist das also gut so? Ja, man vergisst zumindest mal nichts. Noch besser hingegen, und für WordPress selbst funktioniert das ja schon seit geraumer Zeit: Seit Version 5.5 gibt es automatische Updates für Plugins und Themes. Gegen dem Vergessen und für das zeitnahe einspielen ist das sicherlich die bessere Variante.

Jetzt alles? Nein, immer noch nicht. Das mag alles für den privaten, kleinen Blog wunderbar funktionieren. In größeren Umgebungen oder wenn zum Beispiel via Webshop im WordPress Umsatz generiert wird sind automatische Plugin Updates alles andere als ideal. Zu oft funktionierte hinterher irgendeine wichtige Komponente nicht mehr richtig und braucht erst noch einen Folgepatch bis alles wieder so läuft wie es soll. Das bekommt man mit Testumgebungen und Testszenarien in Griff. Sobald im Test alles richtig läuft kann man die gleichen Updates auf die Produktion ausrollen. Das ist dann das „ganz große Kino“ 🙂