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!


Binny V A wrote:
You could remove all the date lines - you need just one command…
THEDAT=`date | awk ‘{print $3$2$6}’`
# Posted on 23-Oct-07 at 8:22 pm
ogosense wrote:
Cool, look forward to testing it.
# Posted on 24-Oct-07 at 8:03 am
Justin Wray wrote:
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
# Posted on 25-Oct-07 at 7:13 am
Peter wrote:
Thanks to everyone for the suggestions for improvements - I will most definitely look into them!
# Posted on 25-Oct-07 at 7:20 am
griff5w wrote:
Awesome! Thank you for posting this. Post more like it!
# Posted on 26-Oct-07 at 10:12 am