Simple cPanel Backup Rotation Script

cPanel has a brilliant backup facility built in, however it only keeps 1 backup per backup type. So if you have daily backups enabled running every day of the week, your previous day's backup will be lost - the same applies to weekly and monthly backups.

This can be a bit of a nuisance if you need to restore a file deleted the day before a backup ran.

So using a simple script that hooks into cPanel's backup script, you can retain backups for any number of days, weeks or months and it will only consume a very minimal amount of space - as the script uses hard links. So only the files that have changed will actually take up disk space.

Backup rotation script

Create a new file /scripts/postcpbackup.sh and put the following in it. You can customise the types of backups to be rotated and the retention period.

#!/bin/sh
# Simple backup directory rotation script for cPanel

# Allows daily, weekly and monthly backups to be kept for X number of days using
hard links for retained backup copies, so disk space usage is extremely minimal
#
# Courtesy of www.SonassiHosting.com - The Magento Hosting experts
# Eg. /backup/cpbackup
BACKUP_ROOT_DIR=/backup/cpbackup
# Eg. daily weekly monthly
BACKUP_TYPES=( daily weekly )
# Eg. 1440 10080 40320 - the number of minutes for each respective backup type
BACKUP_AGE=( 1440 10080 )
# Eg. 7 4 1 - How many historical versions to keep of each backup
BACKUP_RETENTION=( 3 1 )

#######################################
Do not edit anything below this line
#######################################
BACKUP_DATE=date +%F
for (( i = 0 ; i < ${#BACKUP_TYPES[@]} ; i++ )); do
TYPE=${BACKUP_TYPES[$i]}
AGE=${BACKUP_AGE[$i]}
RETENTION=${BACKUP_RETENTION[$i]}
MAX_AGE=expr $RETENTION \* $AGE
MIN_AGE=expr $AGE + 60
if [ ! -d $BACKUP_ROOT_DIR/$TYPE ] || [[ ! find $BACKUP_ROOT_DIR/$TYPE_* -maxdepth 1 -mmin -$MIN_AGE -type d == "" ]]; then
echo "DIR '$TYPE' doesn't exist or previous backup too young ($AGE mins)"
continue
fi
Remove oldest backup
find $BACKUP_ROOTDIR/$TYPE* -maxdepth 1 -type d -mmin +$MAX_AGE -exec rm -rf {} ; > /dev/null 2>&1
mkdir -p $BACKUP_ROOTDIR/$TYPE$BACKUP_DATE
Synchronise files
rsync -a --delete
--link-dest=$BACKUP_ROOT_DIR/$TYPE $TYPE/. $BACKUP_ROOTDIR/$TYPE$BACKUP_DATE/
done

Backup restoration from rotation

Just bear in mind, this code does not integrate into the backup restoration aspect of cPanel - so if you do need to restore/find a file - you will have to rename the folders appropriately.

Eg. to restore a daily backup from 2012-04-03

cd /backups/cpbackup
mv daily{,.previous}
mv daily_2012-04-03 daily

Then use the standard restoration tool in WHM, after the restore is complete, just move the folders back to how they were

mv daily daily_2012-04-03
mv daily.previous daily