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_ROOT_DIR/$TYPE\_* -maxdepth 1 -type d -mmin +$MAX_AGE -exec rm -rf {} \; > /dev/null 2>&1

  mkdir -p $BACKUP_ROOT_DIR/$TYPE\_$BACKUP_DATE

  # Synchronise files
  rsync -a --delete \
    --link-dest=$BACKUP_ROOT_DIR/$TYPE $TYPE/. $BACKUP_ROOT_DIR/$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
  • BBarberi

    Hi,
    thanks for this very useful script.

    Because the script was not executed on the cpbackup folder, I had to change the rsync command to
    rsync -a –delete
    –link-dest=$BACKUP_ROOT_DIR/$TYPE $BACKUP_ROOT_DIR/$TYPE/. $BACKUP_ROOT_DIR/$TYPE_$BACKUP_DATE/