Tam Nguyen Photography

New York Beauty and Fashion Photographer

How to Automatically Back up Your Self-hosted Site on Dreamhost

Posted on August 27, 2012 in Technology, Tips

How to Automatically Back up Your Self-hosted Site on Dreamhost

Let’s talk about website maintenance for a few minutes.

More than a year ago, I posted an entry on how to backup your WordPress site using built-in tools such as W3 Total Cache and WP-DBManager. I didn’t have a content delivery network at the time, so the process was more straight-forward. Now that I have Amazon Cloudfront as my CDN, I have to manually set it up to back up my website nightly. I can’t stress enough how important it is to have a redundant backup system for everything. Redundancy means you have the backups at multiple locations.

Prerequisites: FTP/shell access to your website, WinSCP, some minor Bash-script knowledge.

First, you’ll need to make 2 directories on your host: ‘site_backups‘ and ‘backup_www‘. Note: these directories are NOT part of the webroot directory; they are on the same level with your webroot.

Second, copy everything you have in your webroot directory into ‘backup_www‘. This is for 2 reasons: for easy revert in case anything goes wrong, and for avoiding any file corruptions if the backup process is disrupted (more on this later).

You’ll want to create a Bash shell-script file on your home directory, let’s call it ‘www_backup.sh‘. You are to modify the variables on line 5, 6, and 7 to fit your needs. I’ll walk your through what the rest of the script does.

rsync -ra --delete $WEBROOT backup_www/ >> $current_log_text
tar -zcf $filename backup_www/
find site_backups -type f -mtime +14 -exec rm {} \;
(echo -e 'Something went wrong with website nightly backup. (Error '$is_error')\n' ; cat $current_log_text) | mail -s "$SUBJECT" "$EMAIL"

Download a copy of my www_backup.sh‘ shell script HERE.

First, we need to sync the ‘backup_www/‘ directory with the webroot directory using rsync. Whatever happens to the production directory will happen to the backup directory. Since WP-DBManager backs up my database every 2 days, I’m guaranteed to have multiple backups of it as well.

Second, we zip the ‘backup_www/‘ directory to a tarball, with the date, month, and year at the beginning of the file name. I’ve found that if the zipping process is halted for any reason, all the files in the production directory have the extension of ‘.tar‘, which is very bad news. By having a “bridge” directory, the zipping process will not mess with the files on your website if something happens during the process. Plus, if you accidentally mess something up on your website, just copy and overwrite everything from your ‘backup_www‘ directory to your webroot and it’s fixed!

Third, we delete all the files that are older than 14 days (feel free to change this number to your liking).

Last, send an email to you if any steps of the process went wrong.

“Wait, what about all the gibberish around these commands I see in the script?”, you ask. Those are error checks. Each command executed will have an exit code. Zero means okay, greater than zero if otherwise. I’ve set it up so that each command would throw a different exit code if it didn’t complete. The codes are 1, 2, and 4, respectively. When you get the email, the error codes are added together in a way that you’ll know exactly what went wrong. ‘1’ means it didn’t sync right, ‘2’ means it didn’t zip right, ‘3’ means ‘1’ and ‘2’ didn’t go right, and so on. You’d also get a copy of the error log.

If you’re on Dreamhost, you can visit Goodies >> Cron Jobs to set up the backup task.  For other hosting providers, just log into your SSH and punch in ‘crontab -e’ to edit the task manually. You can use Crontab Code Generator to figure out the right command. Make sure to set the task to run our ‘www_backup.sh‘ file. Mine’s set to run at 12am everyday.

0    0    *    *    *    www_backup.sh

You shouldn’t trust me that I wrote the script correctly, and you should test to see if the script actually works. Run it from your SSH:

./www_backup.sh

Check the ‘site_backup/‘ directory for results.

So now that you have 2 weeks worth of incremental backups, what’s next? Remember what I said earlier about redundancy? I like Dreamhost, but I can’t trust them 100% that my data is safe with them. I need to make sure I have hard copies of my site too. I use WinSCP to download the files from Dreamhost down to my local computer, which is then backed up to an external drive. Just download WinSCP, and make a batch file that looks something like this:

@echo off
echo option echo off>ftpcmd.dat
echo option batch on>>ftpcmd.dat
echo option confirm off>>ftpcmd.dat
echo option transfer binary>>ftpcmd.dat
echo open sftp://username:password@your_ftp_server.com>>ftpcmd.dat
echo cd /home/your_username/site_backups>>ftpcmd.dat
echo lcd "E:\Website backups">>ftpcmd.dat
echo synchronize local -delete>>ftpcmd.dat
echo close>>ftpcmd.dat
echo exit>>ftpcmd.dat
"C:\Program Files (x86)\WinSCP\WinSCP.com" /script="ftpcmd.dat" > winscp.log
IF %ERRORLEVEL% GTR 0 MSG * "Something went wrong with downloading website!"
del ftpcmd.dat

First, we need to turn on a few switches for running the batch file in silent mode. Everything we do is going to be written in a file called ‘ftpcmd.dat‘.

@echo off
echo option echo off>ftpcmd.dat
echo option batch on>>ftpcmd.dat
echo option confirm off>>ftpcmd.dat
echo option transfer binary>>ftpcmd.dat

Then, we connect to our FTP server (change ‘sftp’ to ‘ftp’ if your host doesn’t provide SFTP)

echo open sftp://username:password@your_ftp_server.com>>ftpcmd.dat

We then tell WinSCP where the local folder is, where the remote directory is, and then synchronize the local with the remote. Close and exit when done.

echo cd /home/your_username/site_backups>>ftpcmd.dat (remember this 'site_backups' directory?)
echo lcd "E:\Website backups">>ftpcmd.dat
echo synchronize local -delete>>ftpcmd.dat
echo close>>ftpcmd.dat
echo exit>>ftpcmd.dat

Then we issue the command to run WinSCP with the commands given in the file ‘ftpcmd.dat‘. Any and all errors will be output to a file called ‘winscp.log‘ for auditing. If there’s an error, pop up an alert window. Delete the ‘ftpcmd.dat‘ file when done.

"C:\Program Files (x86)\WinSCP\WinSCP.com" /script="ftpcmd.dat" > winscp.log
IF %ERRORLEVEL% GTR 0 MSG * "Something went wrong with downloading website!"
del ftpcmd.dat

As you might’ve noticed, the script to download the backup files to your local computer was written for Windows. If you have a Mac, you’re on your own. I don’t like Mac.

I set up my local backup to run twice a week at 1am. The remote backup shouldn’t take more than 3-4 minutes (about 10 during first run), so I should have the latest backup by the time I run the local batch file.

If you have any questions or suggestions, feel free to drop your comments below.

Leave a Reply

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