Регулярне створення резервних копій — єдиний надійний захист від збоїв сервера, помилок оновлення CMS або атак зловмисників. Хоча більшість панелей управління (Plesk, cPanel) мають вбудовані інструменти резервного копіювання, збережені ними архіви часто розміщуються в ізольованих системних директоріях, до яких немає прямого доступу через FTP.
У цій статті розглянемо створення універсального Bash-скрипту для VPS/VDS або хостингу з SSH-доступом. Скрипт автоматично створює дампи баз даних MySQL/MariaDB, архівує файли декількох сайтів, збирає їх у підсумковий архів, веде детальний лог і видаляє копії, старіші за 7 днів.
Обмеження та вимоги
Цей підхід розрахований на VPS/VDS сервери або віртуальний хостинг із розширеним SSH-доступом. Для коректної роботи необхідні:
- Доступ до командного рядка (SSH / Bash).
- Утиліти:
mysqldump,tar,find,cron. - Достатні ліміти I/O та RAM (на дешевих тарифах Shared-хостингу процес пакування великих сайтів може зупинятися системою через OOM чи таймаути).
Готовий Bash-скрипт
Створіть файл backup.sh у вашій домашній директорії та додайте в нього наступний код:
#!/usr/bin/env bash
set -euo pipefail
# === КОНФІГУРАЦІЯ ===
VHOST_ROOT="$HOME"
BACKUP_DIR="${VHOST_ROOT}/MyBackup"
LOG_FILE="${VHOST_ROOT}/backup.log"
DB_HOST="localhost"
# Перелік директорій сайтів (відносно VHOST_ROOT)
SITES=(
"httpdocs"
"site2.org.ua"
"site3.org.ua"
)
# Перелік баз даних у форматі "НАЗВА_БД:КОРИСТУВАЧ_БД:ПАРОЛЬ_БД"
DATABASES=(
"db_site1:user1:pass1"
"db_site2:user2:pass2"
"db_site3:user3:pass3"
)
# === ЛОГУВАННЯ ТА ОБРОБКА ПОМИЛОК ===
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> "$LOG_FILE"
}
error_handler() {
local line_no="$1"
local exit_code="${2:-1}"
log "ERROR: Скрипт перервано на рядку ${line_no} з кодом помилки ${exit_code}."
[ -d "${TMP_DIR:-}" ] && rm -rf "$TMP_DIR"
exit "$exit_code"
}
trap 'error_handler ${LINENO} $?' ERR
# === ОСНОВНИЙ ПРОЦЕС ===
log "--- СТАРТ: Початок резервного копіювання ---"
DATE=$(date +%Y-%m-%d_%H-%M)
TMP_DIR="${VHOST_ROOT}/tmp/backup_${DATE}"
ARCHIVE_NAME="full_backup_${DATE}.tar.gz"
mkdir -p "${TMP_DIR}/db" "${TMP_DIR}/files" "${BACKUP_DIR}"
# 1. Дамп баз даних (з прапорцями безблокувального читання InnoDB)
for db_entry in "${DATABASES[@]}"; do
IFS=":" read -r db_name db_user db_pass <<< "$db_entry"
log "DB: Створення дампу бази '${db_name}'..."
mysqldump -h "${DB_HOST}" -u"${db_user}" -p"${db_pass}" \
--single-transaction --quick "${db_name}" > "${TMP_DIR}/db/${db_name}.sql"
log "DB: Дамп '${db_name}' створено."
done
# 2. Архівування файлів сайтів
for site in "${SITES[@]}"; do
if [ -d "${VHOST_ROOT}/${site}" ]; then
log "FILES: Архівування '${site}'..."
tar_status=0
tar -czf "${TMP_DIR}/files/${site}.tar.gz" \
--exclude="${site}/var/cache" \
--exclude="${site}/tmp" \
-C "${VHOST_ROOT}" "$site" || tar_status=$?
# Код 1 у tar означає "файли змінювалися під час читання" (попередження)
if [ "$tar_status" -eq 1 ]; then
log "WARNING: Файли в '${site}' змінювалися під час архівування."
elif [ "$tar_status" -gt 1 ]; then
log "ERROR: Критична помилка tar у '${site}', код: $tar_status"
exit "$tar_status"
fi
log "FILES: Архів '${site}' створено."
fi
done
# 3. Формування підсумкового архіву
log "ARCHIVE: Збирання підсумкового архіву ${ARCHIVE_NAME}..."
tar -czf "${BACKUP_DIR}/${ARCHIVE_NAME}" -C "${TMP_DIR}" .
log "ARCHIVE: Збережено у ${BACKUP_DIR}/${ARCHIVE_NAME}."
# 4. Ротація (видалення архівів, старіших за 7 днів)
log "ROTATION: Видалення копій, старіших за 7 днів..."
find "${BACKUP_DIR}" -type f -name "full_backup_*.tar.gz" -mtime +7 -delete
# 5. Очищення тимчасової директорії
rm -rf "${TMP_DIR}"
log "--- УСПІХ: Резервне копіювання завершено ---"
Кроки налаштування
1. Надання прав на виконання
Після створення файлу дайте йому права на виконання:
chmod +x ~/backup.sh2. Додавання завдання до Cron
Відкрийте планувальник завдань поточного користувача:
crontab -eДодайте рядок для автоматичного запуску щонеділі о 03:00:
0 3 * * 0 /bin/bash /home/username/backup.sh > /dev/null 2>&1Перевірка стану виконання
Скрипт логує кожен етап роботи у файл backup.log. У разі аварійного завершення (наприклад, переповнення диска або невірного пароля до БД) у лог запишеться точний номер рядка та код помилки.
Перевірити останні записи у логу можна командою:
tail -n 30 ~/backup.logРезультат: Отримано автономну систему резервного копіювання, яка формує готові архіви у зручній для завантаження по FTP/SFTP директорії без залучення важких плагінів CMS.
