Backing up my VPS

Wanted to outline how I backup my VPS with Linode. Backups are very important. You want to create a plan that's redundant, tested, and foolproof.

First you want to figure out what to back up. For me it's my MySQL data, web, and configuration files to make a rebuild a little easier. For my server this means two directories: /home/user and /etc. To backup MySQL I'll run mysqldump and that file will be saved in my homedir for easy access later.

Now to figure out where you want these files backed up. I really recommend that you back up your files to two locations. There may be times when one isn't accessable and you want to be sure your files are safe. Personally I backup everything on a linux machine that I have at home and on space that I have with http://rsync.net. I highly recommend using rsync.net. For less than $5 they offer a great service with almost no downtime. Check their site for details. Either way, for the purposes of this script we're backing up to another ssh enabled server using rsync (talking about the program, not the service here.)

You can also use Amazon's Simple Storage Service (S3) but inital setup can be a pain for people new to the service and rsync.net won't charge you for data transfer.

Since you will (hopefully) running this script automatically through you will not be there every time to enter your password for your remote machines when you start to copy files over. This is taken care of with SSH keys. Once you create your account on rsync.net you can follow these instructions to create the correct keys http://www.rsync.net/resources/howto/ssh_keys.html The process is close to creating keys to connect back to your home (or other) server http://www.ece.uci.edu/~chou/ssh-key.html

So now you should have almost everything needed. A what you want to back up, a remote location to back up to, and a way to ssh in to that location with no password. Next up, creating your rsync command. (If I mean rsync the command I will just say rsync, the service is rsync.net) First, you want to be VERY careful of what paths you use with rsync. It is not uncommon for noobs to try to backup their storage location on to the location they are trying to back up. This will generally destroy all of your data. Be careful and for now use the --dry-run flag until you are ready to perform your first backup.

This is the command that I use:

rsync -vrtz --del --delete-excluded --exclude-from="/home/user/.rsync/exclude" "/home/user" accountID@server.rsync.net:myvps/home

If you're unfamiliar with rsync I'll give a quick rundown. rsync is a utility for copying files from one location to another. It's biggest strength is syncronyzing those locations where only files that have been changed will be copied. What we're creating here is an copy of a directory on your server to another location.

Now, for the flags I'm using in order:

  • verbose I like to see this output and cron emails me the results nightly
  • recursive This is important as it goes through all subfolders
  • preserve modification times Fairly important to me as it helps comparing files easier later on
  • compress Saves on bandwidth and transfer time by sacrificing a little cpu
  • receiver deletes during xfer, not before I'm not keeping files deleted on the server. This removes them from the backup loaction
  • also delete excluded files from dest dirs if you add files to your exclude from file this will remove ones copied already
  • --exclude-from= A list of files and folders you do not want backed up. Logs and cache files are a good idea to place here. Use the full path so the file can be found when ran through cron.

Again, TEST THE COMMAND ABOVE WITH --dry-run and tweak it until you have all of the files backing up with no issues and errors. Watch your output for files that you may need to exclude from backing up and add them to your exclude list. 

Once that's all set you're ready to create a script. Save the below gist as backup.sh on your server. Make sure you change all of the paths and server information to your own. run `chmod 755 backup.sh` Run the script as root to test it out then add the script to root's cron.

This script assumes that you're backing up everything in your homedir. (This is where I keep my sites) Your MySQL and /etc data will reside here, be copied to your remote backup, then your /etc backup will be removed. Mine was a bit large so I wanted to save the space.

Now to add another location to your script just duplicate the rsync line and change your server information where appropriate. I have a machine running Ubuntu at home with a drive dedicated to backups. This drive uses 'Back in time' to create daily snapshots. This is great for when you remove a file and don't notice until days later. Since this script runs daily the --del flag will remove any files you trashed even if it was an accident. Trust me, I've had it happen a few times :)