linux-server-tools/daily-backup/backup.sh

300 lines
7.9 KiB
Bash
Raw Normal View History

#!/bin/bash
## Remote Server Backup Script
## Author: Ze'ev Schurmann
## Reddit: u/thisiszeev
## License: GPL-3.0 or later
## This script can only backup one server. So you need a seperate folder for each server. Put this file in each folder and apply
## the relative settings to each server. If you want to get Telegram notifications then check the API documents on the Telegram
## Website. Use a cron job to schedule each run. If you have more than one server, then stagger them. If you are backing up to a
## local machine that is not on redundant power, schedule each backup to run more than once a day, just incase of a power failure
## during a backup. The script will know if the last attempt was successful or not.
## Dependancies:
## rsync, ssh, tar, gzip, wget
## make sure you have key pair authentication setup for ssh. Rsync must be installed on both the remote server and the local machine.
## Use the SQLDumps script to export all MySQL and MariaDB databases on the server. Ensure the SQLDump runs long before this script
## runs to ensure that all databases are completely dumped.
## Example crontab entries (exclude the ##)
## 30 2 * * * root cd /media/backupdrive/server1 && bash backup.sh
## 30 5 * * * root cd /media/backupdrive/server2 && bash backup.sh
## 30 8 * * * root cd /media/backupdrive/server1 && bash backup.sh
## 05 11 * * * root cd /media/backupdrive/server2 && bash backup.sh
## 30 14 * * * root cd /media/backupdrive/server1 && bash backup.sh
## 30 17 * * * root cd /media/backupdrive/server2 && bash backup.sh
## 30 20 * * * root cd /media/backupdrive/server1 && bash backup.sh
## 30 23 * * * root cd /media/backupdrive/server2 && bash backup.sh
## Please consider making me small donation. Even though my scripts are open source and free to use, I still need to eat. And the
## occasional bottle of wine also goes down well.
## $5 buys me a cup of coffee
## $10 buys me a nice burger
## $20 buys me a bottle of wine
## Anything above that will be awesome as well.
## You can send me a donation via Paypal https://www.paypal.com/paypalme/thisiszeev
## Drop me a message on Reddit if you do make a donation.
## Support is only offered freely to those who donate $20 or more.
## Your donation contributes to further development.
## If you need a custom script, contact me on Reddit for pricing.
## Telegram API and Channel Settings
## Set usetelegram to true to get sent Telegram notifications. The Telegram API documentation covers how to obtain a bot key and how
## to assign the bot to a channel. Channels are used as it means notifications can be sent to more than one person if they are all
## in the same channel.
usetelegram=false
tgapi="placekeyhere"
tgch="placechannelhere"
## Backup Settings
## patharray contains a list of the folders you need to backup.
patharray=("/var/log" "/var/www" "/var/sqldumps" "/var/mail" "/var/vmail")
## serverlogin is your SSH login
serverlogin="root@server1.example.com"
servername="Server1"
## keepday is the day of the week you want for you weekly backups.
keepday="sunday"
function ShiftMonths {
echo "Shifting months and copying $dayname.tar.gz to month1.tar.gz" >> backup.log
rm month6.tar.gz
mv month5.tar.gz month6.tar.gz
mv month4.tar.gz month5.tar.gz
mv month3.tar.gz month4.tar.gz
mv month2.tar.gz month3.tar.gz
mv month1.tar.gz month2.tar.gz
cp $dayname.tar.gz month1.tar.gz
}
function ShiftWeeks {
echo "Shifting weeks and copying sunday.tar.gz to week1.tar.gz" >> backup.log
rm week5.tar.gz
mv week4.tar.gz week5.tar.gz
mv week3.tar.gz week4.tar.gz
mv week2.tar.gz week3.tar.gz
mv week1.tar.gz week2.tar.gz
mv sunday.tar.gz week1.tar.gz
ln -s week1.tar.gz sunday.tar.gz
}
function PrepareFiles {
if [ ! -f sunday.tar.gz ]; then
touch sunday.tar.gz
echo "Init Sun"
fi
if [ ! -f monday.tar.gz ]; then
touch monday.tar.gz
echo "Init Mon"
fi
if [ ! -f tuesday.tar.gz ]; then
touch tuesday.tar.gz
echo "Init Tue"
fi
if [ ! -f wednesday.tar.gz ]; then
touch wednesday.tar.gz
echo "Init Wed"
fi
if [ ! -f thursday.tar.gz ]; then
touch thursday.tar.gz
echo "Init Thu"
fi
if [ ! -f friday.tar.gz ]; then
touch friday.tar.gz
echo "Init Fri"
fi
if [ ! -f saturday.tar.gz ]; then
touch saturday.tar.gz
echo "Init Sat"
fi
if [ ! -f month1.tar.gz ]; then
touch month1.tar.gz
echo "Init M1"
fi
if [ ! -f month2.tar.gz ]; then
touch month2.tar.gz
echo "Init M2"
fi
if [ ! -f month3.tar.gz ]; then
touch month3.tar.gz
echo "Init M3"
fi
if [ ! -f month4.tar.gz ]; then
touch month4.tar.gz
echo "Init M4"
fi
if [ ! -f month5.tar.gz ]; then
touch month5.tar.gz
echo "Init M5"
fi
if [ ! -f month6.tar.gz ]; then
touch month6.tar.gz
echo "Init M6"
fi
if [ ! -f week1.tar.gz ]; then
touch week1.tar.gz
echo "Init W1"
fi
if [ ! -f week2.tar.gz ]; then
touch week2.tar.gz
echo "Init W2"
fi
if [ ! -f week3.tar.gz ]; then
touch week3.tar.gz
echo "Init W3"
fi
if [ ! -f week4.tar.gz ]; then
touch week4.tar.gz
echo "Init W4"
fi
if [ ! -f week5.tar.gz ]; then
touch week5.tar.gz
echo "Init W5"
fi
for ((n=0; n<${#patharray[@]}; n++))
do
mkdir -p "./backup${patharray[$n]}"
done
}
dom=$( date +%d )
if [ -f backup.log ]; then
check=$( tail -1 backup.log )
if [[ -z $check ]]; then
sleep 0.1s
elif [[ $check == "T_$dom" ]]; then
echo "Backup already completed successfully today!"
exit
fi
fi
firstruncheck=$( ls -1 | grep "tar.gz")
if [[ -z $firstruncheck ]]; then
PrepareFiles
fi
SECONDS=0
if [[ $usetelegram == true ]]; then
string="Starting backup of $servername."
wget -qO- "https://api.telegram.org/bot$tgapi/sendMessage?chat_id=$tgch&text=$string" &> /dev/null
fi
dow=$( date +%u )
if [ $dow == "1" ]
then
dayname="monday"
elif [ $dow == "2" ]
then
dayname="tuesday"
elif [ $dow == "3" ]
then
dayname="wednesday"
elif [ $dow == "4" ]
then
dayname="thursday"
elif [ $dow == "5" ]
then
dayname="friday"
elif [ $dow == "6" ]
then
dayname="saturday"
else
dayname="sunday"
fi
echo "Start: $( date )" >> backup.log
for ((n=0; n<${#patharray[@]}; n++)); do
if [ -z $1 ]; then
rsync -avhPz --delete "$serverlogin:${patharray[$n]}/" "./backup${patharray[$n]}/"
elif [ $1 == "quiet" ]; then
rsync -avhqz --delete "$serverlogin:${patharray[$n]}/" "./backup${patharray[$n]}/"
else
rsync -avhPz --delete "$serverlogin:${patharray[$n]}/" "./backup${patharray[$n]}/"
fi
done
echo "Rsync complete: $( date )" >> backup.log
echo "Day of Week = $dow | Day of Month = $dom" >> backup.log
echo "Generating $dayname.tar.gz" >> backup.log
rm $dayname.tar.gz
if [ -z $1 ]; then
tar -czvf $dayname.tar.gz ./backup
elif [ $1 == "quiet" ]; then
tar -czf $dayname.tar.gz ./backup
else
tar -czvf $dayname.tar.gz ./backup
fi
if [ $dom == "1" ]; then
ShiftMonths
elif [ $dom == "01" ]; then
ShiftMonths
fi
if [ $dayname == $keepday ]
then
ShiftWeeks
fi
temp=( $( du -b ./backup/ | tail -1 ) )
size1=${temp[0]}
size2=$( stat -c%s $dayname.tar.gz )
size1si=$( numfmt --to=iec-i --suffix=B --format="%9.2f" $size1 )
size2si=$( numfmt --to=iec-i --suffix=B --format="%9.2f" $size2 )
size2percent=$(( size2 * 100 ))
ratio=$( expr $size2percent / $size1 )
duration=$SECONDS
echo "Finished: $( date )" >> backup.log
echo "Data size: $size1si | Archive size: $size2si | Ratio: $ratio%" >> backup.log
echo "T_$dom" >> backup.log
tail -n 5000 backup.log > temp.log
rm backup.log
mv temp.log backup.log
if [[ $usetelegram == true ]]; then
echo "Backup of $servername Complete: $( date )" >> tg.txt
echo "Data Size: $size1si" >> tg.txt
echo "Archive Size: $size2si" >> tg.txt
echo "Ratio: $ratio%" >> tg.txt
echo "Duration: $( TZ=UTC0 printf '%(%H:%M:%S)T\n' $duration )" >> tg.txt
string=$( cat tg.txt )
wget -qO- "https://api.telegram.org/bot$tgapi/sendMessage?chat_id=$tgch&text=$string" &> /dev/null
rm tg.txt
fi