300 lines
7.9 KiB
Bash
Executable File
300 lines
7.9 KiB
Bash
Executable File
#!/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
|