How to Backup Hosted WordPress to a Home Server
If you are running a website on a VPS, you will want to back it up, so that the work you put into it is not lost. There are a myriad of ways of performing backups. The most simplest is to use the options provided by your hosting provider, sometimes this will have a fee associated with it. However if you are tech savvy and comftable using the linux command line then you an use the scripts shown here to be in control of your own backup solution.
In wordpress there are two important parts to backup so you could restore your website if there is a technical issue, or if you migrate to a new provider. your html website itself, and the associated mysql database. The script backs up both parts into a single zip file
Backup Process
- tarzip to local server
- remove old backups
- pull backups from remote to local
- automate it!
Backups: Rule of Three
If you dont have three backups then you dont have a backup!
In general, you should have 3 copies of anything you care about in 2 different formats, and at least 1 copy should be an off-site backup.
The scripts shown here, make a local backup on the hosting site, then these are pulled to your local server. Furthermore you should set another script to backup to the cloud or your NAS from there, to makesure the rule of 3 is met!
Backup Script
make a copy of this script for each wordpress site on your hosting VPS.
#!/bin/bash
# Set the date format, filename and the directories where your backup files will be placed and which directory will be archived.
NOW=$(date +"%Y-%m-%d-%H%M")
FILE="website-backup.$NOW.tar"
BACKUP_DIR="/home/user/backups"
WWW_DIR="/var/www/html/mywebsite/"
# MySQL database credentials
DB_USER="wordpress_user"
DB_PASS="wordpress_password"
DB_NAME="wordpress_db"
DB_FILE="db.$NOW.sql"
# Tar transforms for better archive structure.
WWW_TRANSFORM='s,^var/www/html/mysebsite,www,'
DB_TRANSFORM='s,^home/user/backups,database,'
# Create the archive and the MySQL dump
tar -cvf $BACKUP_DIR/$FILE --transform $WWW_TRANSFORM $WWW_DIR
mysqldump -u$DB_USER -p$DB_PASS $DB_NAME > $BACKUP_DIR/$DB_FILE
# Append the dump to the archive, remove the dump and compress the whole archive.
tar --append --file=$BACKUP_DIR/$FILE --transform $DB_TRANSFORM $BACKUP_DIR/$DB_FILE
rm $BACKUP_DIR/$DB_FILE
gzip -9 $BACKUP_DIR/$FILE
Cron Jobs
To ensure the scripts run every day, edit a file in /etc/cron.daily/ to execute your script location. Or put the whole script itself into cron if you prefer.
#!/bin/bash
#remove files older than 7 days ending in .gz from the directory /home/user/backups
find /home/user/backups -mtime +7 -name '*.gz' -exec rm {} \;
#execute the website backupscript
/home/user/scripts/backup.sh
Remote Sync
The script above makes remote daily backups on your hosting platform, now we need to pull those to your home server with rsync. The following short script, which again be a cron job can achieve this. The prerequisite to the rsync working without password is to have publickey encryption setup with the hosting server.
fr@server:/etc/cron.daily$ cat wp_backups
#!/bin/bash
find /bigdrive/wp_backups/mywebsite -mtime +7 -name '*.gz' -exec rm {} \;
rsync vpss21:backups/* /bigdrive/wp_backups
one common error is when testing a script it works, but when cron executes it the script fails. The usual cause is because the cron user is root, so ensure the root user has correct permissions and for remote scp ensure the private key is in /root/.ssh
So now the website and mysql database are backed up every day on the remote server. In addition you should make a backup of scripts being used and things like nginx config and cron jobs in /etc. This does not have to be every day, but grab an /etc/ tarbundle whenever making config changes.
Test the backups
finally we need to test that the backups actually work! Install wordpress on a local VM or another server and make sure that you can successfully unzip the backup and restore the database and the website onto another server.