My server backup solution

I'd like to share something with you today and that is the backup solution that I use on my web server. My server powers my personal website and a couple of other small sites too.

Actually I lied earlier - what I'm going to share today is only part of my backup solution, which backs up the database and the files in my main website folder and the folders for each of my virtual hosts (the sites on subdomains of my main domain).

So let's dissect my solution quickly.

I have a shell script which performs these backups and it gets run nightly in the early hours of the morning using cron. What the script does is it takes a mysqldump of the database, uses tar to backup the relevant directories.

The backups are stored in /root/Backups, but the script also mirrors them to a secondary drive I also have in my server, so there are always two copies of every backup at any one time. If one drive fails, the backups should still be found on the other, is the theory.

The script also has one final cool feature - it automatically prunes out older backups from both locations, so I don't run out of disk space, but I still have plenty of backups saved in case I need to restore from one older than the most recent.

So that's all very well and good - but you want to see some code right? Well, it's your lucky day.

#!/bin/bash

DATE1=`date | awk '{print $3}'`
DATE2=`date | awk '{print $2}'`
DATE3=`date | awk '{print $6}'`

THEDATE="${DATE1}${DATE2}${DATE3}"

KEEPORIG=10
KEEPSECOND=30

KEEPSQLORIG=30
KEEPSQLSECOND=50

ORIGDIR="/root/Backups"
SECONDDIR="/secondarydir"
APACHEDIR="/var/www/html"
VHOSTSDIR="/var/www/vhosts"

MYSQLUSER=root
MYSQLPASS=pass

cd ${ORIGDIR} # chdir to the right dir
tar -cjvf "./MainApache_${THEDATE}.tar.bz2" ${APACHEDIR} # tar up apache dir
tar -cjvf "./Vhosts_${THEDATE}.tar.bz2" ${VHOSTSDIR} # tar up vhosts dir

mysqldump -u ${MYSQLUSER} -p${MYSQLPASS} -A > "./MySQL_${THEDATE}.sql" # dump db
bzip2 "./MySQL_${THEDATE}.sql" # compress db

cp -v "./MainApache_${THEDATE}.tar.bz2" ${SECONDDIR} # copy
cp -v "./Vhosts_${THEDATE}.tar.bz2" ${SECONDDIR} # copy
cp -v "./MySQL_${THEDATE}.sql.bz2" ${SECONDDIR} # copy

# prune .tar.bz2 in original folder
if [ `ls -1 "${ORIGDIR}" | grep .tar.bz2 | wc -l` -gt $KEEPORIG ]; then
i=1
for each in `ls -1t "${ORIGDIR}" | grep .tar.bz2`; do
if [ $i -gt $KEEPORIG ]; then
echo Removing "${ORIGDIR}/${each}"
rm -fv -- "${ORIGDIR}/${each}"
fi
let "i = i + 1"
done
fi

# prune .tar.bz2 in second folder
if [ `ls -1 ${SECONDDIR} | grep .tar.bz2 | wc -l` -gt $KEEPSECOND ]; then
i=1
for each in `ls -1t "${SECONDDIR}"`; do
if [ $i -gt $KEEPSECOND ]; then
echo Removing "${SECONDDIR}/${each}"
rm -fv -- "${SECONDDIR}/${each}"
fi
let "i = i + 1"
done
fi

# prune db dumps in original folder
if [ `ls -1 "${ORIGDIR}" | grep .sql.bz2 | wc -l` -gt $KEEPSQLORIG ]; then
i=1
for each in `ls -1t "${ORIGDIR}" | grep .sql.bz2`; do
if [ $i -gt $KEEPSQLORIG ]; then
echo Removing "${ORIGDIR}/${each}"
rm -fv -- "${ORIGDIR}/${each}"
fi
let "i = i + 1"
done
fi

# prune db dumps in second folder
if [ `ls -1 "${SECONDDIR}" | grep .sql.bz2 | wc -l` -gt $KEEPSQLSECOND ]; then
i=1
for each in `ls -1t "${SECONDDIR}" | grep .sql.bz2`; do
if [ $i -gt $KEEPSQLSECOND ]; then
echo Removing "${SECONDDIR}/${each}"
rm -fv -- "${SECONDDIR}/${each}"
fi
let "i = i + 1"
done
fi

If you want an easily downloadable version of said script, feel free to grab it here.

Enjoy!

Avatar for peter Peter Upfold - http://peter.upfold.org.uk/

Peter Upfold is a technology enthusiast from the UK. Peter’s interest in Linux stems back to 2003, when curiosity got the better of him and he began using SUSE 9.0. Now he runs Linux Mint 9 on the desktop, runs a CentOS-based web server from home for his personal website and dabbles in all sorts of technology things across the Windows, Mac and open source worlds.

Home » Articles »

Discussion: My server backup solution

  1. Binny V A (guest)

    # Posted on 23 October 2007 at 08:22 PM

    You could remove all the date lines - you need just one command... THEDAT=date | awk '{print $3$2$6}'



  2. ogosense (guest)

    # Posted on 24 October 2007 at 08:03 AM

    Cool, look forward to testing it.



  3. Justin Wray (guest)

    # Posted on 25 October 2007 at 07:13 AM

    Check the man page for date, linked below. You could also make things a lot easier and cleaner by using the + switch in the command and specify specific output.

    Example:

    date +%m%d%y-%H%M:%S would output 102407-100945, you could do this in any order and any format you wish. 10-24-07-10-09-45, so on and so forth.

    Letters and characters can be included in this output. date '+DATE: %m/%d/%y%nTIME:%H:%M:%S' would show as:

    DATE: 10/24/07 TIME:10:09:45

    Although this all may seem a bit over complicated here, take a look at the man page where it is clearly laid out. You will realize you have a lot more control and options of the date output and can save yourself from the repetitive awk lines and the task of combining said lines back together.


    man date > http://unixhelp.ed.ac.uk/CGI/man-cgi?date


    Hope this helps, Justin M. Wray



  4. Peter (guest)

    # Posted on 25 October 2007 at 07:20 AM

    Thanks to everyone for the suggestions for improvements - I will most definitely look into them!



  5. griff5w (guest)

    # Posted on 26 October 2007 at 10:12 AM

    Awesome! Thank you for posting this. Post more like it!



Home » Articles » My server backup solution