Bash script WordPress Restore is the conjugate tool for restoring from a backup created by the WordPress Backup script. WordPress restore is one of the most important tasks for a WordPress site administrator for obvious reasons. The script presented in this post guarantees a way to “reproducibly restore” a WordPress site and it’s accompanying database. The statement is quoted because there is a caveat. Such is only true on the same hardware and configuration, for the most part.
The reasons for that is that the devil is in the details of a WordPress restore. This is especially true if you are going from one platform to another, i.e. from an Amazon EC2 instance to a locally hosted test server running Ubuntu on older HP workstation hardware. We’ll get to that at the end of the discourse.
This post is part of the Bash scripts for fun and leisure series.
The requirements to restore a WordPress website are:
- You have sudo on the server.
- You have the proper access and permissions to write the document root ( /var/www/html ) of the WordPress installation.
- The ability to change permissions and ownership within document root, i.e. sudo.
- You can execute tar, gzip, and mysql with the necessary permissions.
- The restore archive lives in the same folder as the script, or the full path to the archive file is passed to the script.
- You have appropriate database permissions to write/modify/drop a database. However the best way to restore the database is via the administrator/root database user (not to be confused with system root).
The script is a fairly straightforward reversal of the backup script. It includes consistency checking the file and database backups.
#! /bin/bash # DO NOT LEAK THIS SCRIPT # IT HAS CRITICAL DATABASE DATA! # Configure variables. _sn=$(date +"%Y%m%dT%H%M%S") _default="\e[39m" _red="\e[31m" _green="\e[32m" _magenta="\e[35m" _backup_owner=<the account that owns the backups> _db_user=<the database username> _db_pwd=<the database password, enclosed in double quotes> _db_name=<the name of your database> _sitename=<your site name or whatever you want as prefix> # DO IT FOR SITE! echo -e $_magenta$_sitename" Website Code Restore" echo -e "Version: 20230331" $_default # Check if we have a filename passed. if [ $# -ne 1 ]; then echo "Usuage: restore_wordpress.sh <backup file name without extension>" exit fi _backupCF=$1'.tgz' _backupCFCS=$1'.tgz.asc' _backupDB=$1'.sql.gz' _backupDBCS=$1'.sql.gz.asc' # Check if the files are present. for i in $_backupCF $_backupCFCS $_backupDB $_backupDBCS do if [ ! -f $i ]; then echo -e $_red"Missing file: "$_default$i echo -e $_red"Can't continue without file!"$_default exit fi done echo -e $_red"Checking file integrity..."$_default for i in $_backupCFCS $_backupCFCS do sha256sum --status -c $i if [ $? -ne 0 ]; then echo -e $_red" File "$_default$i$_red" failed verification."$_default echo -e $_red"Can't continue with corrupted file."$_default exit fi done echo -e $_red"Starting website code restore..."$_defaultp pushd /var/www sudo tar --overwrite --recursive-unlink -xzf $_backupCF if [ $? -ne 0 ]; then echo -e $_red"Errors detected in code restore."$_default echo -e $_red"Can't continue because code may be corrupted"$_default popd exit fi popd echo -e $_green"Done restoring "$_sitename" code!"$_default echo "" # DO IT FOR DATABASE! echo -e $_magenta$_sitename" Website Database Restore" echo -e "Version: 20230331"$_default gunzip $_backupDB if [ $? -ne 0 ]; then echo -e $_red"Errors detected in unpacking database archive."$_default echo -e $_red"Can't continue because database may be corrupted"$_default exit fi _dbsqlfile=$1'.sql' mysql -p$_db_pwd -u $_db_user $_db_name < $_dbsqlfile if [ $? -ne 0 ]; then echo -e $_red"Errors detected in restoring the database"$_default echo -e $_red"Site may be corrupted!"$_default exit fi echo -e $_green"Done restoring "$_sitename" database!"$_default echo -e $_green"*** ALL DONE ***"$_default
4: The Devil
There are several details that can bite you when restoring a site. The devil appears when restoring to something other than the original, or a very similar, server. These issues result from differences in server configurations, such as which Apache modules are present and active. Those issues also apply to other components of the LAMP stack. Harder to debug are issues occurring from the contents of the database. Plugins may use restored database data in unexpected or incorrect ways. Sometimes, in the case of migration or replication to a significantly different server, substantial modification of the configuration and database may be necessary, including disabling of certain WordPress plugins, i.e. the Google reCAPTCHA plugin. Some examples of the issues that can crop up are:
- Different server versions / active modules and/or configurations.
- Different database versions / configurations / permissions and/or ports.
- Different web root locations.
- Broken re-directions or blocked logins because of the local URL being different from the original server URL. I.e. example.com vs. test.example.com.
- Administrator email addresses may be different, i.e. email@example.com vs. firstname.lastname@example.org
- Database entries referencing incorrect objects or objects that no longer exist.