WARNING! AUTOMATE BACKUP BEFORE AUTOMATE UPDATE-UPGRADE!
While keeping WordPress including its plugins and themes up to date on a daily basis is a important thing to avoid beeing hacked and abused to spread malware, it must be said, that automating self-hosted wordpress installations is no simple task.
In order to avoid any mishaps (as it has happened before!!!) it is HIGHLY recommended to AUTOMATICALLY backup 1) all fiels in web root 2) the database BEFORE the automated update-upgrade and also test the restore process! After restore everything still working as it should? Good! Advance to automated updates-upgrades! NOT BEFORE! WARNING SEND!
automatic (daily, hourly?) updates of everything internet-reachable is important.
- of course developers need to provide timely updates for possible cybersec problems
- users/admins need working update methods that work with minimum downtime
the wordpress “automatic core and plugin auto-updates” feature, has been php-implemented into wordpress for a while and sometimes it even works.
but somteimes it does not (!?).
- so there might be a reliable mechanism required to:
- make an backup
- then reliably run wordperss core and plugin auto update on daily basis
if the user runs it own webserver (vm or dedicated server): https://github.com/wp-cli/wp-cli + the following script 🙂 can do that.
also check out: https://wp-cli.org/
update: 2022
something must have gone wrong.
added “update translations” to the script.
so … updating self hosted wordpress “manual” way, still seems to be ONLY solid option. 🙁
==> /var/log/apache2/domain.com-error.log <== [Tue Dec 13 13:11:18.913569 2022] [php:error] [pid 416927] [client xxx.xxx.xxx.xxx:17253] PHP Fatal error: Uncaught Error: Call to undefined function trailingslashit() in /var/www/html/domain.com/public_html/wp-includes/class-wp-textdomain-registry.php:1 03\nStack trace:\n#0 /var/www/html/domain.com/public_html/wp-includes/l10n.php(784): WP_Textdomain_Registry->set()\n#1 /var/www/html/domain.com/public_html/wp-includes/load.php(1401): load_textdomain()\n#2 /var/www/html/domain.com/public_html/wp-includes/load.php(162): wp_load_translations_early()\n#3 /var/www/html/domain.com/public_html/wp-settings.php(37): wp_check_php_mysql_versions()\n#4 /var/www/html/domain.com/public_html/wp-config.php(93): req uire_once('...')\n#5 /var/www/html/domain.com/public_html/wp-load.php(50): require_once('...')\n#6 /var/www/html/domain.com/public_html/wp-blog-header.php(13): require_once('...')\n#7 /var/www/html/domain.com/public_ht ml/index.php(17): require('...')\n#8 {main}\n thrown in /var/www/html/domain.com/public_html/wp-includes/class-wp-textdomain-registry.php on line 103
snapshot/backup before update:
because things might break, and then a restore to working state is possible.
GNU Linux Bash – simple backup web root and mysql mariadb database in one go script
install:
the default apache2 user is called www-data and is per default not allowed to login
lsb_release -d; # tested on Description: Debian GNU/Linux 11 (bullseye) su - root mkdir software cd software # download the software curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar # check integrity php wp-cli.phar --info # install chmod +x wp-cli.phar mv - wp-cli.phar /usr/local/bin/wp # temporarily allow login usermod -s /bin/bash www-data # become that user su - www-data # cd into a wordpress installation cd /var/www/html/some-domain.com/ wp --info # or wp cli info OS: Linux 5.10.0-15-amd64 #1 SMP Debian 5.10.120-1 (2022-06-09) x86_64 Shell: /bin/sh PHP binary: /usr/bin/php8.1 PHP version: 8.1 php.ini used: /etc/php/8.1/cli/php.ini MySQL binary: /usr/bin/mysql MySQL version: mysql Ver 15.1 Distrib 10.5.15-MariaDB, for debian-linux-gnu (x86_64) using EditLine wrapper SQL modes: WP-CLI root dir: phar://wp-cli.phar/vendor/wp-cli/wp-cli WP-CLI vendor dir: phar://wp-cli.phar/vendor WP_CLI phar path: /var/www/html/some-domain.com WP-CLI packages dir: WP-CLI global config: WP-CLI project config: WP-CLI version: 2.6.0 # what version of wordpress is installed? wp core version --extra WordPress version: 6.0.1 Database revision: 53496 TinyMCE version: 4.9110 (49110-20201110) Package language: en_US # update wordperss, if update is available wp core update Success: WordPress is up to date. # list all installed plugins wp plugin list +--------------------------+----------+--------+---------+ | name | status | update | version | +--------------------------+----------+--------+---------+ | antispam-bee | active | none | 2.11.1 | +--------------------------+----------+--------+---------+ # update plugins wp plugin update --all # disable login again for non-root apache2 default user usermod -s /sbin/nologin www-data
script it:
vim /root/scripts/wordpress_update.sh #!/bin/bash # what to backup WEBROOT=/var/www/html # temporarily allow non-root apache2 user to login usermod -s /bin/bash www-data echo "===== wordpress automatic update single wordpress in web root ====" INSTALLATION=$WEBROOT echo "currently installed:"; su www-data -c "wp core version --path=$INSTALLATION"; echo "..... if updates available, updating:" echo "...core"; su www-data -c "wp core update --path=$INSTALLATION"; echo "...themes"; su www-data -c "wp theme update --all --path=$INSTALLATION"; echo "...plugins"; su www-data -c "wp plugin update --all --path=$INSTALLATION"; # echo "===== wordperss automatic update multiple wordpress in web root =====" # for FULLPATH in $WEBROOT/*; do # if [ -d "$FULLPATH" ]; then # BASENAME=$(basename $FULLPATH); # # INSTALLATION=$FULLPATH; # # might need modification like this: # # INSTALLATION=$FULLPATH/public_html; # # echo "=== updating $INSTALLATION ===" # echo "currently installed:"; su www-data -c "wp core version --path=$INSTALLATION"; # echo "..... if updates available, updating:" # echo "...core"; su www-data -c "wp core update --path=$INSTALLATION"; # echo "...themes"; su www-data -c "wp theme update --all --path=$INSTALLATION"; # echo "...plugins"; su www-data -c "wp plugin update --all --path=$INSTALLATION"; # fi # done # disable login again for non-root apache2 default user usermod -s /sbin/nologin www-data echo "=== disable xmlrpc.php because a lot of pwd brute force attacks focus on this file ===" echo "... also via the readme.html the installed version of wordpress can be identified" echo "... the following files were found and renamed to .disabled" find $WEBROOT -type f -name 'xmlrpc.php'; find $WEBROOT -type f -name 'xmlrpc.php' -print0 | xargs --null -I{} mv {} {}.disabled; find $WEBROOT -type f -name 'liesmich.html'; find $WEBROOT -type f -name 'liesmich.html' -print0 | xargs --null -I{} mv {} {}.disabled; find $WEBROOT -type f -name 'readme.html'; find $WEBROOT -type f -name 'readme.html' -print0 | xargs --null -I{} mv {} {}.disabled; find $WEBROOT -type f -name 'license.txt'; find $WEBROOT -type f -name 'license.txt' -print0 | xargs --null -I{} mv {} {}.disabled;
alternative version including update of translations:
#!/bin/bash
# what to backup
WEBROOT=/var/www/html
# temporarily allow non-root apache2 user to login
# /usr/sbin/usermod -s /bin/bash www-data
echo "===== wordperss automatic update all wordpress in web root ====="
for FULLPATH in $WEBROOT/*; do
if [ -d "$FULLPATH" ]; then
BASENAME=$(basename $FULLPATH);
INSTALLATION=$FULLPATH/public_html;
echo "=== updating $INSTALLATION ==="
echo "currently installed:"
wp core version --path=$INSTALLATION
echo "..... if updates available, updating:"
echo "...core"
wp core update --path=$INSTALLATION
echo "...themes"
wp theme update --all --path=$INSTALLATION
echo "...plugins"
wp plugin update --all --path=$INSTALLATION
echo "...translations"
wp language core update --path=$INSTALLATION
fi
done
cron it:
no need for separate cron job just make it part of the (already existing?) daily update script 🙂
crontab -e
# m h dom mon dow command
0 2 * * * /root/scripts/update.sh; # every day 2:00 run updates
cat /root/scripts/update.sh #!/bin/bash echo "=== attempting automatic daily update on $(date '+%Y-%m-%d-%H:%M:%S') ===" | tee -a /scripts/update.sh.log apt update 2>&1 | tee -a /scripts/update.sh.log apt -y upgrade 2>&1 | tee -a /scripts/update.sh.log echo "=== automatically removing un-needed packages (and old kernels) ===" # keeping too many old kernel versions might fill up boot partition apt -y autoremove | tee -a /scripts/update.sh.log echo "=== updating wordpress installations ===" | tee -a /scripts/update.sh.log /root/scripts/wordpress_update.sh | tee -a /scripts/update.sh.log echo "=== fine ===" | tee -a /scripts/update.sh.log echo "" | tee -a /scripts/update.sh.log
manpages:
liked this article?
- only together we can create a truly free world
- plz support dwaves to keep it up & running!
- (yes the info on the internet is (mostly) free but beer is still not free (still have to work on that))
- really really hate advertisement
- contribute: whenever a solution was found, blog about it for others to find!
- talk about, recommend & link to this blog and articles
- thanks to all who contribute!
