Backing up WordPress revisited


For backing up of WordPress sites, I have been using a myriad of backup strategies which rely on a couple of SaaS services. One of the services is Dropbox.

I have been enjoying the perks of a rather outsized Dropbox space limits for a free account. Due to tie-ups with HTC in the past, I had received a fair bit of space from them. This additional storage space is time-limited and had since expired. Additionally, I had participated in the giveaways that Dropbox had for students (while I was still in university) and had maxed out the storage space given through referrals.

Recently, my Dropbox keeps showing me the following notification on my devices:

Your Dropbox is full! Upgrade or refer your friends to get more space.

I have been using Dropbox for many purposes. One of them is to back up some of the sites that I have been maintaining. However, since I have built a NAS (of sorts), I thought I should utilise it more. This NAS has a RAID6 setup, spreading across 6 3TB hard disks.

I had been relying on Updraft plugin to backup to Dropbox. It has been a great plugin that I have been utilising to automate the backups. To change to using my NAS, I have to switch to using either FTP or SFTP. My preference is SFTP. However, SFTP is a paid extension for Updraft. The miser I decide to code out a bash script to run the backup on a scheduled basis instead.

The benefits of doing so are:

  • Learn bash (again).
  • Offloading the processing to generate backups from WordPress to the server itself.

The script that I have done is available as a gist:

#!/bin/bash
# remotebackup.sh
# usage: remotebackup.sh client_domain
# this assumes that we have already placed ssh keys on the remote server
# default variable values
isRoot=false
backup_recency_days=30
case $1 in
robertsky.com)
user=root
isRoot=true
site_dir=/home/admin/web/robertsky.com/public_html
backup_dir=/home/admin/web/robertsky.com/backup
exclude=wp-content/cache,wp-content/updraft
host=$1
;;
esac
exclude_expanded=' '
if [ ! -z "$exclude" ]
then
# https://stackoverflow.com/questions/918886/how-do-i-split-a-string-on-a-delimiter-in-bash
IFS=',' read -ra excludee <<< "$exclude"
for i in "${excludee[@]}"; do
exclude_expanded="${exclude_expanded}–exclude=${i} "
done
fi
exclude_expanded=`echo $exclude_expanded`
wp_root_user_check=' '
if [ "$isRoot" = true ]
then
wp_root_user_check='–allow-root'
fi
wp_root_user_check=`echo $wp_root_user_check`
# https://zaiste.net/posts/a_few_ways_to_execute_commands_remotely_using_ssh/
# Multi-line command using Heredoc
ssh -T $user@$host << EOSSH
cd $site_dir
# https://www.guyrutenberg.com/2010/02/28/improved-ftp-backup-for-wordpress/
# always check that there is wp-cli installed.
# to-do: download wp-cli.phar if don't have and then erase it.
db_name=\$(wp config get DB_NAME $wp_root_user_check)
db_user=\$(wp config get DB_USER $wp_root_user_check)
db_pass=\$(wp config get DB_PASSWORD $wp_root_user_check)
db_host=\$(wp config get DB_HOST $wp_root_user_check)
site_dir=`dirname "$site_dir"`/`basename "$site_dir"`
backup_dir=`dirname "$backup_dir"`/`basename "$backup_dir"`
dump_name=\${db_name}-\$(date +%Y%m%d).sql.bz2
mysqldump –user=\${db_user} –password=\${db_pass} –host=\${db_host} \
–databases \${db_name} \
| bzip2 -c > \${backup_dir}/\${dump_name}
if [ "$?" -ne "0" ]; then
echo "mysqldump failed!"
exit 1
fi
tar_name=\${site_dir##*/}-\$(date +%Y%m%d).tar.bz2
tar -cjf \${backup_dir}/\${site_dir##*/}-\$(date +%Y%m%d).tar.bz2 $exclude_expanded \${site_dir}
if [ "$?" -ne "0" ]; then
echo "tar failed!"
exit 2
fi
EOSSH
# second command: rsync to fastbackup folder
rsync -avP $user@$host:$backup_dir/* /mnt/SkyFastBackups/clients/$host/
# third command: delete content in remote backup folder
ssh -T $user@$host "rm $backup_dir/*"
# forth set of commands:
# transfer the content from fastbackup folder to the RAID.
# delete excess backup materials
mv /mnt/SkyFastBackups/clients/$host/* /mnt/ProBox/SkyBackups/clients/$host/
find /mnt/ProBox/SkyBackups/clients/$host -type f -mtime +$backup_recency_days -exec rm {} \;
view raw remotebackup.sh hosted with ❤ by GitHub

Before deploying this script for use, there are a couple of conditions to be fufilled:

  • The target server must have WP-CLI installed.
  • The target server must have a backup folder.
  • The target server has the NAS server’s ssh public key.

This script is written to be reused across different server. This script takes in a set of configured values for the specified domain name. You should add additional sets in the case statement as required.

The script then does a mysqldump of the database and compresses the wordpress installation. You can specify which folder or file to ignore in a comma-delimited manner. The script stores these files in the specified backup folder.

The script then transfers the backup files from the target server to the NAS via rsync. I added a line here to transfer from one mount point to another because the first mount point is actually an SSD and the second is the actual RAID array. I am using it to speed up the transfer speed from the target server to the NAS server. The script deletes the backups in the target server.

The script then deletes older backups in the NAS server.

This script is still a work in progress. There are checks and features that I had thought up, but wasn’t necessary to kickstart the process to change the backup destination, starting with this site. These however should be added as I update the backup options for the other sites. Some of the extra stuff that I want in are:

  • Install WP-CLI on target server.
  • Failing which, extract the database information somehow from wp-config.php.
  • Add checks and exception handling at every possible line where things may break.
  • Adhere to the linter’s suggestions.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.