In this article I would like to share with you a rather simple shell script I made quite some time ago when I was managing VPSs that were serving websites. The VPSs were using CentminMod, which is a super useful LEMP stack auto installer. Using CentminMod you can create several websites within the same VPS and it handles automatically many tedious tasks.
In order to automatically get backups of the websites' files along with the databases I made this script which in combination with another one it would ftp these files safely to another location.
A list of features this script includes are given below:
- Verbose details upon execution.
- Notifications through Pushover upon failure or success.
- Email the results.
- Delete backups older than 5 days
- Skips schema databases and all databases with underscore.
- Reports size of each database.
So lets see the script itself.
#!/bin/bash
datenow=`date +"%Y%m%d"`
#user used for databases backup
USER=""
#password for the user above
PASSWORD=""
#all files backup path
path="/root/sitesBackups/"
#pushover details
TOKEN=""
USERID=""
#Email to send notifications to
MAIL=""
#the path where your sites files are
sitespath="/home/nginx/domains/"
STATUS="/root/sitesBackups/statusfile.$datenow"
siteslist=$(ls $sitespath)
# If the directory does not exist, make it please
if [ ! -d $path ]; then
mkdir -p $path
else
:
fi
# SITES FILES BACKUP
printf "these sites will be backed up\n $siteslist\n"
cd $path
var1=0
for site in $siteslist; do
tar -cf $site$datenow.tar $sitespath$site
gzip $site$datenow.tar
gunzip -c $site$datenow.tar.gz | tar t > /dev/null
successcode=$?
if [ $successcode -ne 0 ]; then
curl -s \
-F "token=$TOKEN" \
-F "user=$USERID" \
-F "message=$site ERROR BACKING UP === errorcode = $successcode " \
-F "priority=1"\
https://api.pushover.net/1/messages.json
printf "\n\n$site ERROR BACKING UP === errorcode = $successcode \n\n" >> $STATUS
((var1++))
else
printf "\n$site Backed up with EXITCODE [ $successcode ]\n" >> $STATUS
fi
done
# DATABASES BACKUP
DBS="$(mysql -u$USER -p$PASSWORD -Bse 'show databases')"
echo "$DBS"
errorcounter=0 #innitializing a variable to count errors in mysqldump
#if your db starts with an _ then ignore it this way you can create dbs with _ if you want them ignored
#need to add a list of databases so you can add a database you need to be ignored
for db in $DBS; do
if [[ "$db" != "information_schema" ]] && [[ "$db" != _* ]] && [[ "$db" != "performance_schema" ]] ; then
printf "Dumping database: $db\n"
mysqldump --force --opt --user=$USER --password=$PASSWORD --databases $db > $path/`date +%Y%m%d`.$db.sql
exitcode=$?
gzip $path/$datenow.$db.sql
FILESIZE=$(stat -c%s "$path/$datenow.$db.sql.gz")
printf "$db Backed up with EXITCODE [ $exitcode ] and with size $FILESIZE bytes\n";
#create an if to notify us in case of bad mysqldump
if [ $exitcode -ne 0 ]; then
curl -s \
-F "token=$TOKEN" \
-F "user=$USERID" \
-F "message=$db ERROR BACKING UP === errorcode = $exitcode " \
-F "priority=1"\
https://api.pushover.net/1/messages.json
printf "\n\n$db ERROR BACKING UP === errorcode = $exitcode \n\n" >> $STATUS
((errorcounter++))
else
printf "\n$db Backed up with EXITCODE [ $exitcode ] and with size $FILESIZE bytes\n" >> $STATUS
fi
fi
done
# To remove old database backups
if [ $errorcounter -ne 0 ] || [ $var1 -ne 0 ]; then
printf "Not deleting anything due to errors in mysqldump\n" >> $STATUS
else
find $path -mtime +5 -exec rm {} \;
printf "\nFiles older than 5 days have been deleted\n" >> $STATUS
fi
# Send a Pushover Notification
curl -s \
-F "token=$TOKEN" \
-F "user=$USERID" \
-F "message=server is $(hostname) $(cat $STATUS)" \
-F "priority=0"\
https://api.pushover.net/1/messages.json
# Send by email
printf "Server hostname is $(hostname)\n$(cat $STATUS)" | mail -s "$(hostname) Backup Results" $MAIL
Lets explain a bit the code above. Lines 5-14 contain variables that are required to be filled by the user.
USER
andPASSWORD
need to contain the credentials of a user who has access to the database so it can take a backup usingmysqldump
.path
is where you would like the backups to be stored.TOKEN
andUSERID
are related to the Pushover service, if you would like to receive notification using it.MAIL
is the email where you want the results to be mailed to.
- Lines 16-18 have three variables that are the
sitespath
which is the location where the directories of the sites are located,siteslist
the list of the sites in thesitespath
andSTATUS
which is a file where the script saves the results from the backup of the directories and the databases. Thedatenow
is only the current date so we could differentiate between executions. - Lines 22-27, it checks if the path where we will store the backups exists and if it does not exist it creates the directory.
- Lines 32-52, we make the backups of the directories and notify through Pushover if we have a failure.
- Lines 56-88, the dump of the databases happens, where we are notified through Pushover if something goes wrong and we also get printed details of the size of each database.
- Lines 91-97, we delete already existing backups that are older than 5 days.
- Lines 100-109, we report through Pushover and Email the final Results that are stored in the
STATUS
file.
TIP
You can add this script in a cronjob so it can be executed automatically
In order to do this you need to run crontab -e
and add a line similar to this 0 0 */2 * * /root/tools/dbbackup.sh 2>/dev/null
, which will execute the script every two days. Dont forget to make the script executable!
Disclaimer: I have not tested this script recently but I believe it would work. Please make sure you know what you are doing as it will delete files older than five days when it is executed!