Зручний і простий скрипт резервного копіювання для Linux з відправленням email-сповіщень
- Олександр Мойсеюк
- Лінукс та сервер
- Переглядів: 1502
-
Never LOSE the DATA -
Трапився одного разу простий проект, якому потрібно було налаштувати резервне копіювання для файлів сайту і бази даних. Гарні люди підказали, що досить чогось максимально простого, аж до написаного власноруч. Було вирішено так і зробити. Важливість резервного копіювання тут розписувати не буду, кожен свідомий користувач ПК це може розказати не гірше.
Ключові моменти:
Сайт має кілька основних директорій, такі як директорія скриптів, зображення сайту та прикріплені в публікаціях документи. З міркувань безпеки це окремі каталоги. Вміст статей включно з шляхами до файлів зберігається в БД.
План рішення:
- Організувати збереження різних типів даних з різною частотою.
- Налаштувати гнучкість і універсальність програми.
- Забезпечити інформативність резервних копій, використовуючи в назвах архівів час виконання та назви директорій
- Додати просте сповіщення на електронну пошту у випадку невдачі.
- Надати можливість налаштовувати термін збереження бекапів.
Отже директорії документів та зображень, а також БД зберігаємо щодня, скрипти сайту редагуються рідко, тому їх зберігаємо раз в тиждень.
Поїхали!
Розмістимо скрипти в окремій спеціальній директорії (в будь-якій на бажання). Створюємо її командою
mkdir /usr/local/backup
Відкриємо файл який буде нашим скриптом:
nano /usr/local/backup/run
і вставимо наступні рядки:
#!/bin/bash # # script for backup by Son of Sky # # name of archived dir in path /path/to/you.site name=moodledata backup_dir= /path/to/you.site # where backups will be situated backup_to=/path/to/you/backups # format of output date and email curdate=`date +%Y-%m-%d` curtime=`date +%Y-%m-%d-%H-%M` email=Ця електронна адреса захищена від спам-ботів. Вам потрібно увімкнути JavaScript, щоб побачити її. # goin to the dir cd ${backup_dir} # check the day-directory and make it if no if [ ! -d ${backup_to}/${curdate} ] then mkdir ${backup_to}/${curdate} chmod 777 ${backup_to}/${curdate} fi # check parameters and use name if nothing if [ $# -eq 0 ] ; then # tar arguments: j - archive in progressive bz2 format, c - create buckup, f - use archive ${name}.format tar -jcf ${name}.tar.bz2 ${name} } else # we can change dirs in params tar -jcf ${name}.tar.bz2 $* fi # if success move file to the day-directory and rename if [ $? = 0 ] ; then mv ${name}.tar.bz2 ${backup_to}/${curdate}/${name}_${curtime}.tar.bz2 echo "$curtime - Backup created successfully. It took $SECONDS seconds." else echo "$curtime - Error during creating backup ${name}. It took $SECONDS seconds." | mail -s "System - Backup was not created ${curtime}" ${email} fi
Зробимо файл виконуваним:
chmod 750 /usr/local/backup/run
Трохи пояснень простою мовою стосовно роботи скрипта. Спочатку задаємо значення змінних, які будемо використовувати. (Примітка: після назв змінних не можна ставити пробіл, а відразу =, інакше це буде сприйматися як команда). Потім програма переходить у задану директорію, наприклад, каталог користувача і паралельно створює директорію сьогоднішньої дати. Далі перевіряються передані в команді параметри (це в нашому випадку назви каталогів для архівації) і якщо нічого не вказано то використовуємо назву і власне проводимо архівацію файлів. Якщо попередня команда повертає 0, тобто успіх, виконується завершальний етап: перейменування та переміщення архіву в каталог дня. У випадку невдачі, на вказану електронну адресу надсилається просте сповіщення.
В результаті маємо один скрипт для різних каталогів, який фіксує дату і час створення архіву в назві файлу, поміщає всі архіви до однієї зручної директорії, названої поточною датою, і повідомляє нам на електронну адресу у випадку невдачі.
Отже з файлами все прекрасно. Перейдемо до БД.
nano /usr/local/backup/sql
Скрипт для бекапів бази:
#!/bin/bash # # script for backup by Son of Sky # name=database backup_db=your_database db_user=db_user db_pass=YOURMEGAPASSWORD backup_to=/path/to/you/backups curdate=`date +%Y-%m-%d` curtime=`date +%Y-%m-%d-%H-%M` mail=Ця електронна адреса захищена від спам-ботів. Вам потрібно увімкнути JavaScript, щоб побачити її. cd ${backup_to} if [ ! -d ${backup_to}/${curdate} ] then mkdir ${backup_to}/${curdate} chmod 777 ${backup_to}/${curdate} fi # create backup.sql, compress it, move it, rename it and delete source mysqldump -u${db_user} -p${db_pass} ${backup_db} > ${backup_db}.sql && tar -jcf ${name}.tar.bz2 ${backup_db}.sql && mv ${name}.tar.bz2 ${backup_to}/${curdate}/${name}_${curtime}.tar.bz2 && rm ${backup_db}.sql if [ $? = 0 ] ; then echo "$curtime - Backup created successfully. It took $SECONDS seconds." else echo "$curtime - Error during creating backup ${name}. It took $SECONDS seconds" | mail -s "System - Backup was not created ${curtime}" ${mail} fi
Тут все по аналогії з попереднім, тільки в параметрах вказуємо не директорію, а доступ до бази даних і архівуємо файл створений командою mysqldump. На завершення:
chmod 750 /usr/local/backup/sql
І довершимо все автоматичним видаленням застарілих резервних копій. Будемо зберігати файли місяць
nano /usr/local/backup/remove_old
Вміст:
#!/bin/bash # # script for remove backup by Son of Sky # BACKUP_TO=/path/to/you/backups mydate=`date --date="30 day ago" +%Y-%m-%d` curtime=`date +%Y-%m-%d-%H-%M` mail=Ця електронна адреса захищена від спам-ботів. Вам потрібно увімкнути JavaScript, щоб побачити її. if [ -d ${BACKUP_TO}/${mydate} ] then rm -R ${BACKUP_TO}/${mydate} else echo "Dir not created" fi if [ $? = 0 ] ; then echo "$curtime - Backup ${mydate} deleted successfully." else echo "$curtime - Error during deleting backup ${mydate}. " | mail -s "System - Backup was not deleted ${curtime}" ${mail} fi
chmod 750 /usr/local/backup/sql
Щоб було вже зовсім зрозуміло, приведу приклад власної конфігурації
name=files backup_dir= /home/user
І подальшого налаштування файлу cron:
crontab -e
Додамо:
# робимо щодня в різний час 0 5 * * * /usr/local/backup/run files images> /dev/null &2>&1 40 4 * * * /usr/local/backup/sql > /dev/null &2>&1 0 5 * * * /usr/local/backup/remove_old > /dev/null &2>&1 # робимо щовівторка (окремим файлом для забезпечення іншої назви name=public_html) 20 6 * * 2 /usr/local/backup/public_html > /dev/null &2>&1
Фраза > /dev/null &2>&1 додається для того щоб CRON не закидував вас повідомленнями про виконану роботу. Можна створити різні файли для кожної директорії і запускати без параметрів.
/etc/init.d/cron restart
Буду радий вдосконаленням, зауваженням та побажанням.
Бонус. Резервне копіювання конфігів
Гадаю, не складно буде відредагувати під себе.
#!/bin/bash # # script for backup by Son of Sky # # name of archived dir in path /path/to/you.site name=CONFIGS backup_dir=/path/to/your/dir/confs # where backups will be situated backup_to=/path/to/your/dir/confs # format of output date curdate=`date +%Y-%m-%d` curtime=`date +%Y-%m-%d-%H-%M` # goin to the dir cd ${backup_dir} # check the day-directory and make it if no if [ ! -d ${backup_to}/${curdate} ] then mkdir ${backup_to}/${curdate} chmod 777 ${backup_to}/${curdate} fi #php cp /etc/php5/fpm/pool.d/www.conf ${backup_dir}/${curdate}/ cp /etc/php5/fpm/php.ini ${backup_dir}/${curdate}/ if [ $? = 0 ] ; then echo " Backup of PHP configs created successfully." else echo "System - Backup of PHP configs was not created " fi # NGINX CONFIG cp /etc/nginx/nginx.conf ${backup_dir}/${curdate}/ cp /etc/nginx/sites-available/default ${backup_dir}/${curdate}/ cp /etc/nginx/sites-available/phpmyadmin.cde.conf ${backup_dir}/${curdate}/ if [ $? = 0 ] ; then echo " Backup of NGINX configs created successfully." else echo "System - Backup of NGINX configs was not created " fi # VSFTPD config cp /etc/vsftpd.conf ${backup_dir}/${curdate}/ cp /etc/pam.d/vsftpd ${backup_dir}/${curdate}/ if [ $? = 0 ] ; then echo " Backup of VSFTPD configs created successfully." else echo "System - Backup of VSFTPD configs was not created " fi # MySQL config cp /etc/mysql/my.cnf ${backup_dir}/${curdate}/ if [ $? = 0 ] ; then echo " Backup of MySQL configs created successfully." else echo "System - Backup of MySQL configs was not created " fi tar -jcf ${name}.tar.bz2 ${backup_dir}/${curdate} # if success delete the day-directory and rename file if [ $? = 0 ] ; then mv ${name}.tar.bz2 ${backup_to}/${name}_${curtime}.tar.bz2 && rm -R ${backup_dir}/${curdate} echo "Backup of ALL confs created successfully. " else echo "Error during creating backup ${name}. " fi