Автоматическое резервное копирование WordPress: Скрипты, Cron и Облако

Вы настроили Nginx, оптимизировали PHP-FPM, защитили сайт Fail2ban и Cloudflare. Но что произойдет, если сервер упадет, хостинг заблокирует аккаунт или случайная команда rm -rf удалит всё? Без бэкапов вы потеряете месяцы работы.

В этом руководстве мы создадим систему автоматического резервного копирования без использования тяжелых плагинов вроде UpdraftPlus. Вместо этого напишем легкие bash-скрипты, настроим системный cron и загрузим бэкапы в облако. Это быстрее, надежнее и не нагружает сайт.

Почему не стоит использовать плагины для бэкапов

Плагины резервного копирования (UpdraftPlus, BlogVault, Duplicator) кажутся удобным решением, но у них есть серьезные недостатки:

  • Нагрузка на сервер: создание бэкапа через PHP требует много RAM и CPU, особенно для больших сайтов
  • Таймауты: если сайт большой, скрипт может упереться в max_execution_time и бэкап не завершится
  • Зависимость от WordPress: если сайт упал с белым экраном смерти, вы не сможете восстановить его через админку
  • Хранение на том же сервере: многие плагины по умолчанию хранят бэкапы локально — при падении диска вы теряете и сайт, и бэкапы

Системный подход через bash-скрипты и cron решает все эти проблемы: бэкапы создаются на уровне ОС, не нагружают PHP и могут сразу отправляться в облако.

Шаг 1: Создание скрипта резервного копирования

Создадим скрипт, который делает две вещи: дамп базы данных и архив файлов сайта.

sudo nano /usr/local/bin/wp-backup.sh

Вставьте следующий код:

#!/bin/bash

# Конфигурация
BACKUP_DIR="/var/backups/wordpress"
SITE_DIR="/var/www/wordpress"
DB_NAME="custom_code_db"
DB_USER="custom_code_user"
DB_PASS="your_password"
DATE=$(date +%Y-%m-%d_%H-%M-%S)
KEEP_DAYS=30

# Создаем директорию для бэкапов
mkdir -p $BACKUP_DIR

# 1. Дамп базы данных
echo "Creating database dump..."
mysqldump -u$DB_USER -p$DB_PASS --single-transaction --quick --lock-tables=false $DB_NAME | gzip > $BACKUP_DIR/db_$DATE.sql.gz

# 2. Архив файлов (исключаем кэш и временные файлы)
echo "Creating files archive..."
tar -czf $BACKUP_DIR/files_$DATE.tar.gz \
    --exclude='wp-content/cache' \
    --exclude='wp-content/upgrade' \
    --exclude='wp-content/backup-*' \
    --exclude='*.log' \
    $SITE_DIR

# 3. Удаляем старые бэкапы (старше KEEP_DAYS дней)
echo "Cleaning old backups..."
find $BACKUP_DIR -name "db_*.sql.gz" -type f -mtime +$KEEP_DAYS -delete
find $BACKUP_DIR -name "files_*.tar.gz" -type f -mtime +$KEEP_DAYS -delete

echo "Backup completed: $DATE"

Сделайте скрипт исполняемым:

sudo chmod +x /usr/local/bin/wp-backup.sh

Шаг 2: Тестирование скрипта

Запустите скрипт вручную, чтобы убедиться, что всё работает:

sudo /usr/local/bin/wp-backup.sh

Проверьте, что в /var/backups/wordpress/ появились два файла:

ls -lh /var/backups/wordpress/
# Должны увидеть:
# db_2026-06-05_12-00-00.sql.gz
# files_2026-06-05_12-00-00.tar.gz

Шаг 3: Настройка автоматического запуска через cron

Теперь настроим cron для ежедневного запуска бэкапа в 3 часа ночи (когда нагрузка минимальна):

sudo crontab -e

Добавьте строку:

# Ежедневный бэкап WordPress в 3:00
0 3 * * * /usr/local/bin/wp-backup.sh >> /var/log/wp-backup.log 2>&1

Проверьте, что cron добавлен:

sudo crontab -l

Шаг 4: Загрузка бэкапов в облако (S3/Google Drive)

Хранить бэкапы только на сервере — плохая идея. Если диск выйдет из строя, вы потеряете и сайт, и бэкапы. Настроим загрузку в облако.

Вариант А: Amazon S3 (или S3-совместимое хранилище)

Установите AWS CLI:

sudo apt install awscli -y
aws configure
# Введите Access Key, Secret Key, регион (например, us-east-1)

Обновите скрипт, добавив в конец:

# 4. Загрузка в S3
echo "Uploading to S3..."
aws s3 cp $BACKUP_DIR/db_$DATE.sql.gz s3://your-bucket-name/wordpress/
aws s3 cp $BACKUP_DIR/files_$DATE.tar.gz s3://your-bucket-name/wordpress/

# Удаляем старые бэкапы из S3 (старше KEEP_DAYS дней)
aws s3 ls s3://your-bucket-name/wordpress/ | grep "db_" | awk '{print $4}' | while read file; do
    if [[ $file < $(date -d "$KEEP_DAYS days ago" +%Y-%m-%d) ]]; then
        aws s3 rm s3://your-bucket-name/wordpress/$file
    fi
done

Вариант Б: Google Drive (через rclone)

Установите rclone:

sudo apt install rclone -y
rclone config
# Создайте remote "gdrive" с доступом к Google Drive

Добавьте в скрипт:

# 4. Загрузка в Google Drive
echo "Uploading to Google Drive..."
rclone copy $BACKUP_DIR/db_$DATE.sql.gz gdrive:wordpress-backups/
rclone copy $BACKUP_DIR/files_$DATE.tar.gz gdrive:wordpress-backups/

# Удаляем старые бэкапы из Google Drive
rclone delete gdrive:wordpress-backups/ --min-age ${KEEP_DAYS}d

Шаг 5: Инкрементальные бэкапы (опционально)

Если сайт большой и ежедневные полные бэкапы занимают слишком много места, используйте инкрементальные бэкапы файлов:

# Создаем инкрементальный бэкап (только изменившиеся файлы)
tar -czf $BACKUP_DIR/files_incremental_$DATE.tar.gz \
    --listed-incremental=$BACKUP_DIR/snapshot.snar \
    --exclude='wp-content/cache' \
    $SITE_DIR

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

Шаг 6: Мониторинг и уведомления

Добавьте уведомления о статусе бэкапа через email или Telegram.

Email-уведомления (через msmtp)

sudo apt install msmtp msmtp-mta -y

Настройте /etc/msmtprc и добавьте в скрипт:

# Отправка email при ошибке
if [ $? -ne 0 ]; then
    echo "Backup failed on $(hostname) at $DATE" | mail -s "WordPress Backup Failed" admin@custom-code.ru
fi

Telegram-уведомления (через curl)

# Создайте бота через @BotFather, получите токен и chat_id
TELEGRAM_BOT_TOKEN="your_bot_token"
TELEGRAM_CHAT_ID="your_chat_id"

# Отправка уведомления
curl -s -X POST https://api.telegram.org/bot$TELEGRAM_BOT_TOKEN/sendMessage \
    -d chat_id=$TELEGRAM_CHAT_ID \
    -d text="✅ WordPress backup completed: $DATE"

Шаг 7: Восстановление из бэкапа

Бэкапы бесполезны, если вы не умеете их восстанавливать. Разберем процесс.

Восстановление базы данных:

# Распаковываем дамп
gunzip /var/backups/wordpress/db_2026-06-05_12-00-00.sql.gz

# Импортируем в MySQL
mysql -u custom_code_user -p custom_code_db < /var/backups/wordpress/db_2026-06-05_12-00-00.sql

Восстановление файлов:

# Останавливаем веб-сервер
sudo systemctl stop nginx php8.2-fpm

# Распаковываем файлы
sudo tar -xzf /var/backups/wordpress/files_2026-06-05_12-00-00.tar.gz -C /

# Восстанавливаем права
sudo chown -R www-data:www-data /var/www/wordpress
sudo find /var/www/wordpress -type d -exec chmod 755 {} \;
sudo find /var/www/wordpress -type f -exec chmod 644 {} \;

# Запускаем сервер
sudo systemctl start nginx php8.2-fpm

Чек-лист настройки бэкапов

  • ✅ Скрипт создан и протестирован вручную
  • ✅ Cron настроен на ежедневный запуск (ночью)
  • ✅ Бэкапы загружаются в облако (S3/Google Drive)
  • ✅ Старые бэкапы автоматически удаляются (30 дней)
  • ✅ Настроены уведомления об ошибках
  • ✅ Процесс восстановления протестирован на staging-сервере
  • ✅ Бэкапы хранятся минимум в двух местах (сервер + облако)

Что делать, если проблемы не решаются?

Скрипт не выполняется по cron

Проверьте логи cron:

grep CRON /var/log/syslog
# или
tail -f /var/log/wp-backup.log

Частые причины: неправильные пути к командам (используйте абсолютные пути), отсутствие прав на выполнение, проблемы с переменными окружения.

Бэкапы занимают слишком много места

Уменьшите KEEP_DAYS до 7-14 дней или настройте инкрементальные бэкапы. Также исключите из архива большие файлы (видео, логи):

tar -czf backup.tar.gz --exclude='*.mp4' --exclude='*.log' $SITE_DIR

Дамп базы данных падает с ошибкой

Если база большая, используйте --single-transaction для InnoDB-таблиц (это уже есть в скрипте). Для MyISAM добавьте --lock-tables. Если ошибка "Lost connection to MySQL server", увеличьте max_allowed_packet в MySQL.

Загрузка в облако не работает

Проверьте права доступа (IAM-роли для S3, OAuth для Google Drive). Убедитесь, что bucket/folder существует и у пользователя есть права на запись.

Итог

Автоматическое резервное копирование — это не опция, а обязательная часть настройки WordPress. Потратив 30 минут на создание скрипта и настройку cron, вы получаете страховку от всех возможных проблем: от случайного удаления плагина до полного отказа сервера. Храните бэкапы в облаке, тестируйте восстановление раз в месяц, и спите спокойно.