A handy backup script for remote hosting

I use Media Temple for hosting of websites and Subversion repositories. The quality of service they provide is solid (especially considering the price) and the ability to SSH into the server and dig around at the command line is a huge plus. Unfortunately one of the areas they are lacking in is backups.

Media Temple provide a backup service but it is very limited in terms of capacity and granularity. Their backup function also does not provide any Subversion repository dump support which is crucial if you have ever experienced the pain of recovering from a Berkeleydb corruption.

Below is a script I use to backup my web domains, databases and Subversion repositories to compressed tar archives. Once these have been generated they are uploaded to the Amazon S3 storage cloud to create an off-site backup of off-site resources. The ability to backup directly from Media Temple to Amazon is great because it removes the middle-man (me) and maximises bandwidth usage. Pulling a tonne of data from the United States to New Zealand just to send it back again is certainly not an economical use of Internet resources.

Edit the variables at the top of the file to suit your hosting environment. Remember to set the file's execute permission bit otherwise it is not going to run (e.g. chmod a+x backup_server.sh).

backup_server.sh

#!/bin/sh

# A list of website directories to back up
websites="website1.com website2.com website3.com website4.com"

# A list of subversion repositories to back up
svnrepos="repo1 repo2 repo3 repo4"

# The destination directory to backup the files to
destdir=/var/backups

# The directory where all website domain directories reside
domaindir=/srv/www/vhosts

# The directory where all subversion repositories reside
svndir=/srv/svn

# The MySQL database hostname
dbhost=example.mysqldatabase.com

# The MySQL database username - requires read access to databases
dbuser=exampleuser

# The MySQL database password
dbpassword=examplepassword


echo `date` ": Beginning backup process..." > $destdir/backup.log

# remove old backups
rm $destdir/*.tar.gz

# backup databases
for dbname in `echo 'show databases;' | /usr/bin/mysql -h $dbhost -u$dbuser -p$dbpassword`
do
if [ $dbname != "Database" ];
then
echo `date` ": Backing up database $dbname..." >> $destdir/backup.log
/usr/bin/mysqldump --opt -h $dbhost -u$dbuser -p$dbpassword $dbname > $destdir/$dbname.sql
tar -czf $destdir/$dbname.sql.tar.gz $destdir/$dbname.sql
rm $destdir/$dbname.sql
fi
done

# backup web content
echo `date` ": Backing up web content..." >> $destdir/backup.log
for website in $websites
do
echo `date` ": Backing up website $website..." >> $destdir/backup.log
tar -czf $destdir/$website.tar.gz $domaindir/$website
done

# backup subversion repositories
echo `date` ": Backing up subversion data..." >> $destdir/backup.log
for svnrepo in $svnrepos
do
echo `date` ": Backing up svn repo $svnrepo..." >> $destdir/backup.log
svnadmin dump -q $svndir/$svnrepo > $destdir/$svnrepo.svn
tar -czf $destdir/$svnrepo.svn.tar.gz $destdir/$svnrepo.svn
rm $destdir/$svnrepo.svn
done

echo `date` ": Backup process complete." >> $destdir/backup.log

Once the backup process is complete the archives can be uploaded to Amazon's S3 via the s3backup tool. Follow the instructions as described in Paul Stamatiou's excellent how-to post entitled 'Bulletproof Server Backups with Amazon S3'.

Below is a small script I use to run s3backup which uploads the previously created archives.

s3_backup.sh (again remember to set execute permissions on the file)

#!/bin/sh

# The directory where s3sync is installed
s3syncdir=/usr/local/s3sync

# The directory where the backup archives are stored
backupdir=/var/backups

# The S3 bucket a.k.a. directory to upload the backups into
s3bucket=backups

cd $s3syncdir
./s3sync.rb $backupdir/ $s3bucket:

Once both scripts have been tested they can be added as cron jobs and left to themselves. If you wanted with a bit of tweaking to the s3_backup.sh script (or cron) you could create multiple remote backup versions on S3 just in case an archive gets corrupted or there is a need to restore something overridden in your previous backup.