Перейти до вмісту
Блог › Налаштування ПЗ › Автоматичний бекап сайтів та баз даних на Linux/VPS: універсальний Bash-скрипт із ротацією та логами

Автоматичний бекап сайтів та баз даних на Linux/VPS: універсальний Bash-скрипт із ротацією та логами

Регулярне створення резервних копій — єдиний надійний захист від збоїв сервера, помилок оновлення 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.sh

2. Додавання завдання до 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.

Залишити відповідь

Ваша e-mail адреса не оприлюднюватиметься. Обов’язкові поля позначені *