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!
