BASH скрипт резервного копирования

Дата:
Автор: admin
backup-large.jpg

При проблемах с сайтом или хостингом администратор проекта должен иметь возможность быстро вернуть сайт в рабочее состояние. Для этих целей можно периодически создавать дубликат данных сайта: файлов и базы данных. Этот процесс называется резервным копированием, или бэкапом. При наличии бэкапа администратор сайта в любой момент вернёт работоспособность сломанного сайта или, в некоторых случаях, перенесет сайт на другой сервер.

Резервное копирование - процесс важный, но затратный по времени, если выполнять его вручную. Поэтому создание бекапа стараются автоматизировать, особенно, когда сайт часто обновляется и дубликат надо создавать ежедневно.

Многие хостинги предлагают собственный функционал для создания копии сайта и почти всегда за это взимается плата (за создание копии или за хранение копии на сервере). Но процесс резервного копирования можно сделать бесплатным и использовать только встроенные возможности сервера без стороннего программного обеспечения.

В этой статье будет написан скрипт для выполнения всей рутинной работы по резервному копированию.

Создадим файл с расширением «.sh», например «backup.sh» и в самом начале файла на первой строке напишем обязательную строку: 

#!/bin/bash

Чтобы этот скрипт можно было запустить, необходимо присвоить ему права на исполнение. Для этого на хостинге через файловой менеджер зайдите в свойства созданного файла backup.sh и установите соответствующие права на исполнение файла.

Если вам привычнее работать с консолью, то назначить нужные права через консоль можно командой chmod +x backup.sh. Для отображения консоли на хостингах обычно есть специальные инструменты, как «SSH-консоль», «Терминал» и т.п.

Конфигурация скрипта

Для удобства в самом начале файла создадим условный раздел со значениями будущих параметров. При изменении параметров или при использовании скрипта для другого проекта не нужно будет искать и менять в коде тот или иной параметр, достаточно будет поменять значение в разделе с конфигурацией.

#===== Конфигурация =====
# Имя проекта
PROJECT=my_project
# Дата создания бекапа
DATE=$(date '+%d-%m-%Y_%H-%M')
# Версия concrete5
VERSION=`php ~/mysite.ru/public_html/concrete/bin/concrete5 c5:config get concrete.version` 
# Где лежат файлы проекта
PROJECT_FILES=~/mysite.ru/public_html
# Кодировка базы данных
DB_CHARSET=utf8
# Имя базы данных для резервного копирования
DB=db_name
# имя дампа базы данных
BACKUP_DB=$PROJECT"_c5core-"$VERSION"_db"
# имя для бекапа файлов
BACKUP_FILES=$PROJECT"_c5core-"$VERSION"_files”
# Хост MySQL
DB_HOST=localhost
# Имя пользователя базы данных
DB_USER=db_user
# Пароль от базы данных
DB_PASSWORD=mypassword
# Полный путь до директории с бекапом
BACKUP_DIR=~/BACKUPS/$PROJECT/$DATE

Комментарии перед каждым параметром поясняют его предназначение. Остановимся лишь на некоторых строках.

VERSION - параметр определяет используемую версию ядра cms concrete5. Обратите внимание, что параметр VERSION сработает только для concrete5 версии выше 5.7.5.

DATE - если сайт обновляется редко, а бэкапы делаются раз в неделю, то параметр DATE имеет смысл сократить и не указывать аргументы для вывода часов и минут (%H и %M соответственно)

PROJECT_FILES - это путь до корня проекта, то есть папка, где среди прочих файлов лежит файл index.php.

DB_PASSWORD - не бойтесь держать здесь пароль базы данных, ниже в разделе «Безопасность» будут показаны действия, как запретить доступ к скрипту.

Комментарии в коде

При написании скрипта рекомендуем сопровождать каждое действие комментарием после символа «#». Если захотите улучшить скрипт через год-два, то комментарии помогут вспомнить как работает код и за что отвечает каждая строка.

Cоздание папки для бекапа

При запуске скрипта проверяем существование папки для бэкапов. При отсутствии папки - создадим её.

if [ ! -d "$BACKUP_DIR" ]; then
  mkdir -p $BACKUP_DIR;
  echo "Папка для бекапа успешно создана: $(date '+%d-%m-%Y_%H-%M-%S')"
fi

ключ -p позволяет создать вложенные папки.

Команда Echo

Основное предназначение команды echo - выводить текст в терминал. Но мы хотим записывать все операции в отдельный файл. К сожалению, факт успешного выполнения операции в файл не запишутся, но каждую операцию мы будем сопровождать командой echo с каким-то текстом. Именно это текст мы увидим в логах.

Создание архива файлов:

Для создания архива нужно перейти в папку с файлами командой «cd», иначе файлы в архиве будут расположены с той же структурой, как на сервере, начиная с домашней директории, например, «/home/u/username/mysite.ru/public_html»

cd $PROJECT_FILES || echo "[!!!] ВНИМАНИЕ! Не удалось перейти в папку с проектом! Бекап не создан!" || exit

Для уменьшения размера архива мы исключаем папку с кешем сайта - эти файлы совершенно не нужны в резервной копии.

zip $BACKUP_DIR/$BACKUP_FILES.zip -r * -x 'application/files/cache/*' -q
echo "Архив успешно создан в $(date '+%d-%m-%Y_%H-%M-%S')";

Ключ -r означает, что архивация должна пройти рекурсивно по всем подпапкам.

Ключ -x позволяет указать файлы и папки, которые будут исключены их архива

Ключ -q делает архивацию в тихом режиме, не выводя весь список архивируемых файлов.

Кроме того, архив можно сделать ещё меньше - исключите из архива папку с ядром системы «/concrete». Ядро для каждой версии cms перманентно и при необходимости вы всегда сможете скачать официальный дистрибутив с cms concrete5 и скопировать оттуда папку с ядром системы («/concrete»). Чтобы не ошибиться с номером версии cms - в имена архива и дампа базы мы включаем номер версии cms concrete5 («c5core-VERSION»)

Если вы решили исключить папку с ядром, то после ключа «-x» добавьте пробел и вставьте «'concrete/*'», таким образом строка для создания архива изменится:

zip $BACKUP_DIR/$BACKUP_FILES.zip -r * -x 'concrete/*' 'application/files/cache/*' -q

Создание дампа базы данных

Прописываем команду для создания дампа базы:

mysqldump --user=$DB_USER --host=$DB_HOST --password=$DB_PASSWORD --default-character-set=$DB_CHARSET $DB > $BACKUP_DIR/$BACKUP_DB.sql
echo "Дамп успешно создан в $(date '+%d-%m-%Y_%H-%M-%S')";

Завершение скрипта

На последнем этапе проверим, что архив и дамп существуют. Если хотя бы один файл отсутствует - выводим ошибку. Для полноценного восстановления сайта требуются одновременно и архив, и дамп базы.

if [ -f "$BACKUP_DIR/$BACKUP_FILES.zip" ] && [ -f "$BACKUP_DIR/$BACKUP_DB.sql" ]; then
	echo "Резервная копия создана. Задача завершена.";
	exit 0;
else
	echo "[!!!] ВНИМАНИЕ! Не удалось обнаружить архив файлов и дамп базы. Возможно, резервная копия не создана! ERROR 3";
	exit 3;	
fi

Запуск скрипта:

— Запуск вручную: введите в консоль «./backup.sh» и нажмите «Enter»

— Запуск + запись в лог: ./backup.sh | tee ~/BACKUPS/logs/backup.log

— Запуск через cron: для этого на всех хостингах есть специальный раздел с настройкой CRON.

Безопасность

В начале скрипта в разделе с конфигурацией мы прописали полные данные для подключения к базе. Если всё оставить как есть, то это угрожает безопасности вашего сайта. Дополнительно выполним действия, чтобы злоумышленники не могли получить доступ к файлу.

  • Переименуем наш файл: вместо backup.sh напишем случайный набор букв и цифр, например sdJiLA4Ui4Hjq.sh.
  • В файле «.htaccess» запретим доступ к файлу. Для этого в файле «.htaccess» (создайте его, если он отсутствует) добавьте строки:
<FilesMatch ".(sh)$">
 Order Allow,Deny
 Deny from all
</FilesMatch>
  • Файл со скриптом можно держать не с файлами сайта, а положить в отдельную папку, недоступную извне.

Код скрипта

Объединим весь написанный код в одном месте.

#!/bin/bash
#===== Конфигурация =====
# Имя проекта
PROJECT=my_project
# Дата создания бекапа
DATE=$(date '+%d-%m-%Y_%H-%M')
# Версия concrete5
VERSION=`php ~/mysite.ru/public_html/concrete/bin/concrete5 c5:config get concrete.version` 
# Где лежат файлы проекта
PROJECT_FILES=~/mysite.ru/public_html
# Кодировка базы данных
DB_CHARSET=utf8
# Имя базы данных для резервного копирования
DB=db_name
# имя дампа базы данных
BACKUP_DB=$PROJECT"_c5core-"$VERSION"_db"
# имя для бекапа файлов
BACKUP_FILES=$PROJECT"_c5core-"$VERSION"_files”
# Хост MySQL
DB_HOST=localhost
# Имя пользователя базы данных
DB_USER=db_user
# Пароль от базы данных
DB_PASSWORD=mypassword
# Полный путь до директории с бекапом
BACKUP_DIR=~/BACKUPS/$PROJECT/$DATE

if [ ! -d "$BACKUP_DIR" ]; then
  mkdir -p $BACKUP_DIR;
  echo "Папка для бекапа успешно создана: $(date '+%d-%m-%Y_%H-%M-%S')"
fi

cd $PROJECT_FILES || echo "[!!!] ВНИМАНИЕ! Не удалось перейти в папку с проектом! Бекап не создан!" || exit

zip $BACKUP_DIR/$BACKUP_FILES.zip -r * -x 'application/files/cache/*' -q
echo "Архив успешно создан в $(date '+%d-%m-%Y_%H-%M-%S')";

mysqldump --user=$DB_USER --host=$DB_HOST --password=$DB_PASSWORD --default-character-set=$DB_CHARSET $DB > $BACKUP_DIR/$BACKUP_DB.sql
echo "Дамп успешно создан в $(date '+%d-%m-%Y_%H-%M-%S')";

if [ -f "$BACKUP_DIR/$BACKUP_FILES.zip" ] && [ -f "$BACKUP_DIR/$BACKUP_DB.sql" ]; then
	echo "Резервная копия создана. Задача завершена.";
	exit 0;
else
	echo "[!!!] ВНИМАНИЕ! Не удалось обнаружить архив файлов и дамп базы. Возможно, резервная копия не создана! ERROR 3";
	exit 3;	
fi

От автора

Этот скрипт выполняет простую задачу: создаёт файлы, чтобы сломанный по каким-то причинам сайт можно было вернуть в рабочее состояние. Вы можете взять за основу этот bash-скрипт и дополнить его своим кодом под ваши потребности: настроить выгрузку копий на внешний FTP-сервер, удалять старые неактуальные копии. Для написания bash-скриптов в Интернете можно найти множество мануалов с готовыми кусками кода.

Загрузка беседы

Продолжая просматривать сайт, вы даёте согласие на использование файлов cookie.

Подробнее