Резервное копирование WordPress: автоматизация через Bash и Crontab

Резервное копирование WordPress

Резервное копирование WordPress: автоматизация через Bash и Crontab

Восстанавливая неоднократно WordPress сайты после взломов, сбоев хостинга и случайных удалений, знаете что я понял? В 90% случаев проблема решалась за 5 минут благодаря правильно настроенному бэкапу. Сегодня покажу, как создать bulletproof систему резервного копирования WordPress без платных плагинов — только Bash, Crontab и здравый смысл.

Что нужно бэкапить в WordPress

Новички часто делают одну критическую ошибку — бэкапят только базу данных или только файлы. Для полного восстановления WordPress нужны ОБА компонента:

  • База данных MySQL/MariaDB — все посты, страницы, комментарии, настройки, пользователи
  • Файлы WordPress — wp-content (темы, плагины, загрузки), wp-config.php, .htaccess
  • Дополнительно: конфигурации веб-сервера (Nginx/Apache), SSL сертификаты

Забудьте про папки wp-admin и wp-includes — их можно скачать заново. Бэкапьте только уникальные данные: wp-content, wp-config.php и БД.

Пример 1: Базовый скрипт бэкапа WordPress

Начнём с простого, но рабочего скрипта. Этот код я использую для десятков клиентских сайтов — надёжность проверена временем.

#!/bin/bash
# Файл: /opt/scripts/wp-backup-basic.sh
# Базовый <a class="wpil_keyword_link" href="https://it-apteka.com/category/scripts/"   title="Скрипты" data-wpil-keyword-link="linked"  data-wpil-monitor-id="76">скрипт</a> резервного копирования WordPress

set -euo pipefail  # Прерывать при любой ошибке

# ============= КОНФИГУРАЦИЯ =============
SITE_NAME=&quot;mysite&quot;
WP_ROOT=&quot;/var/www/html/mysite.com&quot;
BACKUP_ROOT=&quot;/backups/wordpress&quot;
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_DIR=&quot;${BACKUP_ROOT}/${SITE_NAME}/${DATE}&quot;

# Данные для подключения к MySQL
DB_NAME=&quot;wordpress_db&quot;
DB_USER=&quot;wp_user&quot;
DB_PASSWORD=&quot;secure_password&quot;
DB_HOST=&quot;localhost&quot;

# Срок хранения бэкапов (дни)
RETENTION_DAYS=30

# ============= СОЗДАНИЕ ДИРЕКТОРИЙ =============
mkdir -p &quot;$BACKUP_DIR&quot;/{files,database}

echo &quot;$(date) - Начало бэкапа WordPress сайта: $SITE_NAME&quot;

# ============= БЭКАП БАЗЫ ДАННЫХ =============
echo &quot;Создание дампа базы данных...&quot;
mysqldump \
  --host=&quot;$DB_HOST&quot; \
  --user=&quot;$DB_USER&quot; \
  --password=&quot;$DB_PASSWORD&quot; \
  --single-transaction \
  --quick \
  --lock-tables=false \
  &quot;$DB_NAME&quot; | gzip &gt; &quot;$BACKUP_DIR/database/${DB_NAME}.sql.gz&quot;

echo &quot;✓ База данных сохранена: ${DB_NAME}.sql.gz&quot;

# ============= БЭКАП ФАЙЛОВ WORDPRESS =============
echo &quot;Архивирование файлов WordPress...&quot;

# Бэкапим только важные директории
tar czf &quot;$BACKUP_DIR/files/wp-content.tar.gz&quot; \
  -C &quot;$WP_ROOT&quot; \
  wp-content \
  --exclude=&#039;wp-content/cache&#039; \
  --exclude=&#039;wp-content/uploads/cache&#039; \
  --exclude=&#039;*.log&#039;

# Сохраняем конфигурационные файлы
cp &quot;$WP_ROOT/wp-config.php&quot; &quot;$BACKUP_DIR/files/&quot; 2&gt;/dev/null || true
cp &quot;$WP_ROOT/.htaccess&quot; &quot;$BACKUP_DIR/files/&quot; 2&gt;/dev/null || true

echo &quot;✓ Файлы заархивированы&quot;

# ============= СОЗДАНИЕ ФИНАЛЬНОГО АРХИВА =============
echo &quot;Создание итогового архива...&quot;
cd &quot;$BACKUP_ROOT/$SITE_NAME&quot; || exit 1
tar czf &quot;${SITE_NAME}_${DATE}.tar.gz&quot; &quot;${DATE}&quot;
BACKUP_SIZE=$(du -h &quot;${SITE_NAME}_${DATE}.tar.gz&quot; | cut -f1)

# Удаляем временную директорию
rm -rf &quot;${DATE}&quot;

echo &quot;✓ Итоговый архив создан: ${SITE_NAME}_${DATE}.tar.gz (${BACKUP_SIZE})&quot;

# ============= ОЧИСТКА СТАРЫХ БЭКАПОВ =============
echo &quot;Удаление бэкапов старше ${RETENTION_DAYS} дней...&quot;
find &quot;$BACKUP_ROOT/$SITE_NAME&quot; -name &quot;*.tar.gz&quot; -type f -mtime +${RETENTION_DAYS} -delete

# ============= ИТОГОВАЯ ИНФОРМАЦИЯ =============
TOTAL_BACKUPS=$(find &quot;$BACKUP_ROOT/$SITE_NAME&quot; -name &quot;*.tar.gz&quot; -type f | wc -l)
TOTAL_SIZE=$(du -sh &quot;$BACKUP_ROOT/$SITE_NAME&quot; | cut -f1)

echo &quot;&quot;
echo &quot;============= БЭКАП ЗАВЕРШЁН =============&quot;
echo &quot;Сайт: $SITE_NAME&quot;
echo &quot;Размер бэкапа: $BACKUP_SIZE&quot;
echo &quot;Всего бэкапов: $TOTAL_BACKUPS&quot;
echo &quot;Общий размер: $TOTAL_SIZE&quot;
echo &quot;Путь: ${BACKUP_ROOT}/${SITE_NAME}/${SITE_NAME}_${DATE}.tar.gz&quot;
echo &quot;==========================================&quot;

Установка и первый запуск

# Создаём необходимые директории
sudo mkdir -p /opt/scripts /backups/wordpress
sudo chmod 700 /backups/wordpress  # Только root может читать бэкапы

# Сохраняем скрипт
sudo nano /opt/scripts/wp-backup-basic.sh
# Вставляем код выше и корректируем параметры

# Делаем исполняемым
sudo chmod +x /opt/scripts/wp-backup-basic.sh

# Тестовый запуск
sudo /opt/scripts/wp-backup-basic.sh

# Проверяем результат
ls -lh /backups/wordpress/mysite/

Пример 2: Продвинутый скрипт с оптимизацией БД

WordPress БД со временем засоряется ревизиями постов, спамом в комментариях, транзиентами. Перед бэкапом можно оптимизировать базу — это сэкономит место и ускорит восстановление.

#!/bin/bash
# Файл: /opt/scripts/wp-backup-advanced.sh
# Продвинутый <a href="https://it-apteka.com/winget-shpargalka-it-inzhenera-po-paketnomu-menedzheru-windows/"  data-wpil-monitor-id="300">скрипт с оптимизацией</a> и проверками

set -euo pipefail

# ============= КОНФИГУРАЦИЯ =============
SITE_NAME=&amp;quot;mysite&amp;quot;
WP_ROOT=&amp;quot;/var/www/html/mysite.com&amp;quot;
BACKUP_ROOT=&amp;quot;/backups/wordpress&amp;quot;
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_DIR=&amp;quot;${BACKUP_ROOT}/${SITE_NAME}/${DATE}&amp;quot;
LOG_FILE=&amp;quot;/var/log/wp-backup.log&amp;quot;

# MySQL настройки
DB_NAME=&amp;quot;wordpress_db&amp;quot;
DB_USER=&amp;quot;wp_user&amp;quot;
DB_PASSWORD=&amp;quot;secure_password&amp;quot;
DB_HOST=&amp;quot;localhost&amp;quot;

# Функция логирования
log() {
    echo &amp;quot;$(date &amp;#039;+%Y-%m-%d %H:%M:%S&amp;#039;) - $1&amp;quot; | tee -a &amp;quot;$LOG_FILE&amp;quot;
}

# ============= ПРОВЕРКИ ПЕРЕД НАЧАЛОМ =============
log &amp;quot;=== Начало бэкапа WordPress: $SITE_NAME ===&amp;quot;

# Проверка существования директории WordPress
if [ ! -d &amp;quot;$WP_ROOT&amp;quot; ]; then
    log &amp;quot;ERROR: Директория WordPress не найдена: $WP_ROOT&amp;quot;
    exit 1
fi

# Проверка подключения к MySQL
if ! mysql -h&amp;quot;$DB_HOST&amp;quot; -u&amp;quot;$DB_USER&amp;quot; -p&amp;quot;$DB_PASSWORD&amp;quot; -e &amp;quot;USE $DB_NAME&amp;quot; 2&amp;gt;/dev/null; then
    log &amp;quot;ERROR: Не удалось подключиться к базе данных&amp;quot;
    exit 1
fi

# Проверка свободного места (минимум 1GB)
FREE_SPACE=$(df -BG &amp;quot;$BACKUP_ROOT&amp;quot; | awk &amp;#039;NR==2 {print $4}&amp;#039; | sed &amp;#039;s/G//&amp;#039;)
if [ &amp;quot;$FREE_SPACE&amp;quot; -lt 1 ]; then
    log &amp;quot;WARNING: Мало свободного места: ${FREE_SPACE}GB&amp;quot;
fi

mkdir -p &amp;quot;$BACKUP_DIR&amp;quot;/{files,database,logs}

# ============= ОПТИМИЗАЦИЯ БАЗЫ ДАННЫХ =============
log &amp;quot;Оптимизация базы данных перед бэкапом...&amp;quot;

# Удаление ревизий постов (оставляем последние 3)
mysql -h&amp;quot;$DB_HOST&amp;quot; -u&amp;quot;$DB_USER&amp;quot; -p&amp;quot;$DB_PASSWORD&amp;quot; &amp;quot;$DB_NAME&amp;quot; &amp;lt;&amp;lt;EOF
DELETE FROM wp_posts WHERE post_type = &amp;#039;revision&amp;#039;;
EOF

# Очистка транзиентов
mysql -h&amp;quot;$DB_HOST&amp;quot; -u&amp;quot;$DB_USER&amp;quot; -p&amp;quot;$DB_PASSWORD&amp;quot; &amp;quot;$DB_NAME&amp;quot; &amp;lt;&amp;lt;EOF
DELETE FROM wp_options WHERE option_name LIKE &amp;#039;_transient_%&amp;#039;;
DELETE FROM wp_options WHERE option_name LIKE &amp;#039;_site_transient_%&amp;#039;;
EOF

# Очистка корзины комментариев
mysql -h&amp;quot;$DB_HOST&amp;quot; -u&amp;quot;$DB_USER&amp;quot; -p&amp;quot;$DB_PASSWORD&amp;quot; &amp;quot;$DB_NAME&amp;quot; &amp;lt;&amp;lt;EOF
DELETE FROM wp_comments WHERE comment_approved = &amp;#039;trash&amp;#039;;
DELETE FROM wp_comments WHERE comment_approved = &amp;#039;spam&amp;#039;;
EOF

# Оптимизация таблиц
mysql -h&amp;quot;$DB_HOST&amp;quot; -u&amp;quot;$DB_USER&amp;quot; -p&amp;quot;$DB_PASSWORD&amp;quot; &amp;quot;$DB_NAME&amp;quot; &amp;lt;&amp;lt;EOF
OPTIMIZE TABLE wp_posts, wp_postmeta, wp_comments, wp_options;
EOF

log &amp;quot;✓ База данных оптимизирована&amp;quot;

# ============= ДАМП БАЗЫ ДАННЫХ =============
log &amp;quot;Создание дампа базы данных...&amp;quot;

mysqldump \
  --host=&amp;quot;$DB_HOST&amp;quot; \
  --user=&amp;quot;$DB_USER&amp;quot; \
  --password=&amp;quot;$DB_PASSWORD&amp;quot; \
  --single-transaction \
  --routines \
  --triggers \
  --quick \
  --lock-tables=false \
  --add-drop-table \
  &amp;quot;$DB_NAME&amp;quot; | gzip &amp;gt; &amp;quot;$BACKUP_DIR/database/${DB_NAME}.sql.gz&amp;quot;

DB_SIZE=$(du -h &amp;quot;$BACKUP_DIR/database/${DB_NAME}.sql.gz&amp;quot; | cut -f1)
log &amp;quot;✓ База данных: ${DB_SIZE}&amp;quot;

# ============= БЭКАП ФАЙЛОВ =============
log &amp;quot;Архивирование файлов WordPress...&amp;quot;

# wp-content с исключениями
tar czf &amp;quot;$BACKUP_DIR/files/wp-content.tar.gz&amp;quot; \
  -C &amp;quot;$WP_ROOT&amp;quot; \
  --exclude=&amp;#039;wp-content/cache/*&amp;#039; \
  --exclude=&amp;#039;wp-content/uploads/cache/*&amp;#039; \
  --exclude=&amp;#039;wp-content/w3tc-config/*&amp;#039; \
  --exclude=&amp;#039;wp-content/backup-*&amp;#039; \
  --exclude=&amp;#039;*.log&amp;#039; \
  --exclude=&amp;#039;*.tmp&amp;#039; \
  wp-content

# Отдельный архив для uploads (обычно самая большая папка)
if [ -d &amp;quot;$WP_ROOT/wp-content/uploads&amp;quot; ]; then
    tar czf &amp;quot;$BACKUP_DIR/files/uploads.tar.gz&amp;quot; \
      -C &amp;quot;$WP_ROOT/wp-content&amp;quot; uploads
    UPLOADS_SIZE=$(du -h &amp;quot;$BACKUP_DIR/files/uploads.tar.gz&amp;quot; | cut -f1)
    log &amp;quot;✓ Uploads: ${UPLOADS_SIZE}&amp;quot;
fi

# Конфигурационные файлы
cp &amp;quot;$WP_ROOT/wp-config.php&amp;quot; &amp;quot;$BACKUP_DIR/files/&amp;quot; 2&amp;gt;/dev/null || true
cp &amp;quot;$WP_ROOT/.htaccess&amp;quot; &amp;quot;$BACKUP_DIR/files/&amp;quot; 2&amp;gt;/dev/null || true

# Сохраняем информацию о версии WordPress
if [ -f &amp;quot;$WP_ROOT/wp-includes/version.php&amp;quot; ]; then
    grep &amp;quot;wp_version&amp;quot; &amp;quot;$WP_ROOT/wp-includes/version.php&amp;quot; &amp;gt; &amp;quot;$BACKUP_DIR/logs/wp-version.txt&amp;quot;
fi

# Список установленных плагинов и тем
find &amp;quot;$WP_ROOT/wp-content/plugins&amp;quot; -maxdepth 1 -type d &amp;gt; &amp;quot;$BACKUP_DIR/logs/plugins-list.txt&amp;quot;
find &amp;quot;$WP_ROOT/wp-content/themes&amp;quot; -maxdepth 1 -type d &amp;gt; &amp;quot;$BACKUP_DIR/logs/themes-list.txt&amp;quot;

FILES_SIZE=$(du -h &amp;quot;$BACKUP_DIR/files/wp-content.tar.gz&amp;quot; | cut -f1)
log &amp;quot;✓ Файлы WordPress: ${FILES_SIZE}&amp;quot;

# ============= СОЗДАНИЕ ФИНАЛЬНОГО АРХИВА =============
log &amp;quot;Создание финального архива...&amp;quot;
cd &amp;quot;$BACKUP_ROOT/$SITE_NAME&amp;quot; || exit 1
tar czf &amp;quot;${SITE_NAME}_${DATE}.tar.gz&amp;quot; &amp;quot;${DATE}&amp;quot;
FINAL_SIZE=$(du -h &amp;quot;${SITE_NAME}_${DATE}.tar.gz&amp;quot; | cut -f1)
rm -rf &amp;quot;${DATE}&amp;quot;

log &amp;quot;✓ Финальный архив: ${FINAL_SIZE}&amp;quot;

# ============= ПРОВЕРКА ЦЕЛОСТНОСТИ =============
log &amp;quot;Проверка целостности архива...&amp;quot;
if tar tzf &amp;quot;${SITE_NAME}_${DATE}.tar.gz&amp;quot; &amp;gt; /dev/null 2&amp;gt;&amp;amp;1; then
    log &amp;quot;✓ Архив корректен&amp;quot;
else
    log &amp;quot;ERROR: Архив повреждён!&amp;quot;
    exit 1
fi

# ============= ОЧИСТКА СТАРЫХ БЭКАПОВ =============
log &amp;quot;Очистка старых бэкапов...&amp;quot;
find &amp;quot;$BACKUP_ROOT/$SITE_NAME&amp;quot; -name &amp;quot;*.tar.gz&amp;quot; -type f -mtime +30 -delete

# ============= СТАТИСТИКА =============
TOTAL_BACKUPS=$(find &amp;quot;$BACKUP_ROOT/$SITE_NAME&amp;quot; -name &amp;quot;*.tar.gz&amp;quot; -type f | wc -l)
TOTAL_SIZE=$(du -sh &amp;quot;$BACKUP_ROOT/$SITE_NAME&amp;quot; | cut -f1)

log &amp;quot;=== Бэкап завершён успешно ===&amp;quot;
log &amp;quot;Размер: ${FINAL_SIZE} | Всего бэкапов: ${TOTAL_BACKUPS} | Общий размер: ${TOTAL_SIZE}&amp;quot;

Пример 3: Бэкап с WP-CLI (профессиональный подход)

WP-CLI — это командная утилита для управления WordPress. С ней можно делать продвинутые операции: экспорт только определённых таблиц, поиск и замена в БД, проверка обновлений.

Установка WP-CLI

# Скачивание WP-CLI
curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar

# Проверка работы
php wp-cli.phar --info

# Установка глобально
chmod +x wp-cli.phar
sudo mv wp-cli.phar /usr/local/bin/wp

# Проверка установки
wp --info

Скрипт бэкапа с WP-CLI

#!/bin/bash
# Файл: /opt/scripts/wp-backup-wpcli.sh
# Бэкап WordPress через WP-CLI

set -euo pipefail

# ============= КОНФИГУРАЦИЯ =============
SITE_NAME=&quot;mysite&quot;
WP_ROOT=&quot;/var/www/html/mysite.com&quot;
BACKUP_ROOT=&quot;/backups/wordpress&quot;
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_DIR=&quot;${BACKUP_ROOT}/${SITE_NAME}/${DATE}&quot;

mkdir -p &quot;$BACKUP_DIR&quot;/{files,database}

echo &quot;$(date) - Бэкап WordPress через WP-CLI&quot;

cd &quot;$WP_ROOT&quot; || exit 1

# ============= ПРОВЕРКА WORDPRESS =============
# Проверка здоровья WordPress
wp core verify-checksums --allow-root || echo &quot;WARNING: Некоторые core файлы изменены&quot;

# Получение информации о сайте
wp core version --allow-root &gt; &quot;$BACKUP_DIR/wp-info.txt&quot;
wp plugin list --allow-root &gt;&gt; &quot;$BACKUP_DIR/wp-info.txt&quot;
wp theme list --allow-root &gt;&gt; &quot;$BACKUP_DIR/wp-info.txt&quot;

# ============= БЭКАП БАЗЫ ДАННЫХ =============
echo &quot;Экспорт базы данных через WP-CLI...&quot;

# Полный дамп
wp db export &quot;$BACKUP_DIR/database/database.sql&quot; --allow-root

# Сжатие
gzip &quot;$BACKUP_DIR/database/database.sql&quot;

# Альтернатива: экспорт только определённых таблиц
# wp db export --tables=wp_posts,wp_postmeta &quot;$BACKUP_DIR/database/posts-only.sql&quot; --allow-root

echo &quot;✓ База экспортирована&quot;

# ============= ОБСЛУЖИВАНИЕ БД ЧЕРЕЗ WP-CLI =============
# Очистка транзиентов
wp transient delete --all --allow-root

# Оптимизация БД
wp db optimize --allow-root

# Поиск и замена URL (если нужно для staging)
# wp search-replace &#039;https://old-domain.com&#039; &#039;https://new-domain.com&#039; --dry-run --allow-root

# ============= БЭКАП ФАЙЛОВ =============
echo &quot;Архивирование файлов...&quot;

tar czf &quot;$BACKUP_DIR/files/wp-content.tar.gz&quot; \
  -C &quot;$WP_ROOT&quot; \
  --exclude=&#039;wp-content/cache&#039; \
  --exclude=&#039;wp-content/backup*&#039; \
  wp-content

# Конфиги
cp wp-config.php .htaccess &quot;$BACKUP_DIR/files/&quot; 2&gt;/dev/null || true

# ============= ФИНАЛЬНЫЙ АРХИВ =============
cd &quot;$BACKUP_ROOT/$SITE_NAME&quot;
tar czf &quot;${SITE_NAME}_${DATE}.tar.gz&quot; &quot;${DATE}&quot;
rm -rf &quot;${DATE}&quot;

echo &quot;Бэкап завершён: ${SITE_NAME}_${DATE}.tar.gz&quot;
echo &quot;Размер: $(du -h ${SITE_NAME}_${DATE}.tar.gz | cut -f1)&quot;

# ============= ПРОВЕРКА ОБНОВЛЕНИЙ =============
cd &quot;$WP_ROOT&quot;
echo &quot;&quot;
echo &quot;=== Доступные обновления ===&quot;
wp core check-update --allow-root || true
wp plugin list --update=available --allow-root || true
wp theme list --update=available --allow-root || true

Пример 4: Бэкап с отправкой в облако и уведомлениями

Локальные бэкапы — это хорошо, но что если сервер сгорит? Правильный подход — отправлять копии в облако. Плюс добавим Telegram уведомления.

#!/bin/bash
# Файл: /opt/scripts/wp-backup-cloud.sh
# Бэкап <a href="https://it-apteka.com/2026/01/28/plaginy-wordpress-oblako-taksonomij-v-bokovuju-panel-bez-boli-i-shamanstva/" title="Плагины WordPress: облако таксономий в боковую панель (без боли и шаманства)"  data-wpil-monitor-id="156">WordPress с отправкой в облако</a>

set -euo pipefail

# ============= КОНФИГУРАЦИЯ =============
SITE_NAME=&quot;mysite&quot;
WP_ROOT=&quot;/var/www/html/mysite.com&quot;
BACKUP_ROOT=&quot;/backups/wordpress&quot;
DATE=$(date +%Y%m%d_%H%M%S)

# MySQL
DB_NAME=&quot;wordpress_db&quot;
DB_USER=&quot;wp_user&quot;
DB_PASSWORD=&quot;secure_password&quot;

# AWS S3
S3_BUCKET=&quot;s3://my-wp-backups/mysite/&quot;
AWS_PROFILE=&quot;default&quot;

# Telegram уведомления
TELEGRAM_BOT_TOKEN=&quot;123456789:ABCdefGHIjklMNOpqrsTUVwxyz&quot;
TELEGRAM_CHAT_ID=&quot;123456789&quot;

# ============= ФУНКЦИИ =============
send_telegram() {
    curl -s -X POST &quot;https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendMessage&quot; \
        -d chat_id=&quot;${TELEGRAM_CHAT_ID}&quot; \
        -d parse_mode=&quot;HTML&quot; \
        -d text=&quot;$1&quot; &gt; /dev/null
}

# ============= НАЧАЛО БЭКАПА =============
send_telegram &quot;🔄 &lt;b&gt;Начало бэкапа WordPress&lt;/b&gt;
📱 Сайт: ${SITE_NAME}
🖥 Сервер: $(hostname)&quot;

TEMP_DIR=&quot;${BACKUP_ROOT}/temp_${DATE}&quot;
mkdir -p &quot;$TEMP_DIR&quot;/{files,database}

# ============= ДАМП БД =============
echo &quot;Создание дампа базы данных...&quot;
mysqldump \
  --user=&quot;$DB_USER&quot; \
  --password=&quot;$DB_PASSWORD&quot; \
  --single-transaction \
  --quick \
  &quot;$DB_NAME&quot; | gzip &gt; &quot;$TEMP_DIR/database/${DB_NAME}_${DATE}.sql.gz&quot;

DB_SIZE=$(du -h &quot;$TEMP_DIR/database/${DB_NAME}_${DATE}.sql.gz&quot; | cut -f1)

# ============= АРХИВИРОВАНИЕ ФАЙЛОВ =============
echo &quot;Архивирование wp-content...&quot;
tar czf &quot;$TEMP_DIR/files/wp-content_${DATE}.tar.gz&quot; \
  -C &quot;$WP_ROOT&quot; \
  --exclude=&#039;wp-content/cache&#039; \
  --exclude=&#039;*.log&#039; \
  wp-content

FILES_SIZE=$(du -h &quot;$TEMP_DIR/files/wp-content_${DATE}.tar.gz&quot; | cut -f1)

# Конфиги
cp &quot;$WP_ROOT/wp-config.php&quot; &quot;$TEMP_DIR/files/&quot;
cp &quot;$WP_ROOT/.htaccess&quot; &quot;$TEMP_DIR/files/&quot; 2&gt;/dev/null || true

# ============= СОЗДАНИЕ ИТОГОВОГО АРХИВА =============
FINAL_BACKUP=&quot;${BACKUP_ROOT}/${SITE_NAME}_${DATE}.tar.gz&quot;
tar czf &quot;$FINAL_BACKUP&quot; -C &quot;$BACKUP_ROOT&quot; &quot;temp_${DATE}&quot;
rm -rf &quot;$TEMP_DIR&quot;

FINAL_SIZE=$(du -h &quot;$FINAL_BACKUP&quot; | cut -f1)

# ============= ОТПРАВКА В AWS S3 =============
echo &quot;Отправка в AWS S3...&quot;
if aws s3 cp &quot;$FINAL_BACKUP&quot; &quot;${S3_BUCKET}&quot; \
  --storage-class STANDARD_IA \
  --profile &quot;$AWS_PROFILE&quot; 2&gt;&amp;1; then
    
    echo &quot;✓ Загружено в S3&quot;
    S3_STATUS=&quot;✅ Загружено в S3&quot;
else
    echo &quot;✗ Ошибка загрузки в S3&quot;
    S3_STATUS=&quot;❌ Ошибка S3&quot;
fi

# ============= ОТПРАВКА НА УДАЛЁННЫЙ СЕРВЕР =============
# Опционально: rsync на второй сервер
# rsync -avz &quot;$FINAL_BACKUP&quot; backup-server:/backups/wordpress/

# ============= ОЧИСТКА ЛОКАЛЬНЫХ БЭКАПОВ =============
# Оставляем только последние 7 дней локально
find &quot;$BACKUP_ROOT&quot; -name &quot;${SITE_NAME}_*.tar.gz&quot; -type f -mtime +7 -delete

# Очистка старых бэкапов в S3 (&gt;30 дней)
aws s3 ls &quot;${S3_BUCKET}&quot; | awk &#039;{print $4}&#039; | while read -r file; do
    if [ -n &quot;$file&quot; ]; then
        FILE_DATE=$(echo &quot;$file&quot; | grep -oP &#039;\d{8}_\d{6}&#039; || echo &quot;&quot;)
        if [ -n &quot;$FILE_DATE&quot; ]; then
            FILE_TIMESTAMP=$(date -d &quot;${FILE_DATE:0:8} ${FILE_DATE:9:2}:${FILE_DATE:11:2}:${FILE_DATE:13:2}&quot; +%s 2&gt;/dev/null || echo 0)
            CURRENT_TIMESTAMP=$(date +%s)
            AGE_DAYS=$(( (CURRENT_TIMESTAMP - FILE_TIMESTAMP) / 86400 ))
            
            if [ &quot;$AGE_DAYS&quot; -gt 30 ]; then
                echo &quot;Удаление старого бэкапа из S3: $file&quot;
                aws s3 rm &quot;${S3_BUCKET}${file}&quot; --profile &quot;$AWS_PROFILE&quot;
            fi
        fi
    fi
done

# ============= ИТОГОВОЕ УВЕДОМЛЕНИЕ =============
TOTAL_LOCAL=$(find &quot;$BACKUP_ROOT&quot; -name &quot;${SITE_NAME}_*.tar.gz&quot; -type f | wc -l)

send_telegram &quot;✅ &lt;b&gt;Бэкап WordPress завершён&lt;/b&gt;

📱 Сайт: ${SITE_NAME}
📦 Размер: ${FINAL_SIZE}
💾 БД: ${DB_SIZE}
📁 Файлы: ${FILES_SIZE}

${S3_STATUS}
🗄 Локальных копий: ${TOTAL_LOCAL}

🕐 Время: $(date &#039;+%H:%M:%S&#039;)&quot;

echo &quot;=== Бэкап завершён успешно ===&quot;

Установка AWS CLI для S3

# Установка AWS CLI
curl &quot;https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip&quot; -o &quot;awscliv2.zip&quot;
unzip awscliv2.zip
sudo ./aws/install

# Настройка credentials
aws configure
# AWS Access Key ID: ваш_ключ
# AWS Secret Access Key: ваш_секретный_ключ
# Default region name: eu-central-1
# Default output format: json

# Создание S3 bucket
aws s3 mb s3://my-wp-backups

# Проверка
aws s3 ls s3://my-wp-backups/

Пример 5: Настройка Crontab для автоматических бэкапов

Скрипты готовы, теперь автоматизируем. Покажу несколько стратегий для разных типов сайтов.

# Открываем crontab
sudo crontab -e

# ============= СТРАТЕГИЯ 1: ЕЖЕДНЕВНЫЙ БЭКАП =============
# Каждый день в 02:00 (для блогов и малых сайтов)
0 2 * * * /opt/scripts/wp-backup-basic.sh &gt;&gt; /var/log/wp-backup-cron.log 2&gt;&amp;1

# ============= СТРАТЕГИЯ 2: ЧАСТЫЕ БЭКАПЫ =============
# Каждые 6 часов (для активных сайтов)
0 */6 * * * /opt/scripts/wp-backup-advanced.sh &gt;&gt; /var/log/wp-backup-cron.log 2&gt;&amp;1

# ============= СТРАТЕГИЯ 3: КОМБИНИРОВАННАЯ =============
# Ежедневный локальный в 01:00
0 1 * * * /opt/scripts/wp-backup-basic.sh &gt;&gt; /var/log/wp-backup-cron.log 2&gt;&amp;1

# Еженедельный с отправкой в облако (воскресенье в 03:00)
0 3 * * 0 /opt/scripts/wp-backup-cloud.sh &gt;&gt; /var/log/wp-backup-cron.log 2&gt;&amp;1

# ============= СТРАТЕГИЯ 4: ДЛЯ ИНТЕРНЕТ-МАГАЗИНОВ =============
# Каждые 4 часа - база данных (заказы, клиенты)
0 */4 * * * /opt/scripts/wp-db-only-backup.sh &gt;&gt; /var/log/wp-backup-cron.log 2&gt;&amp;1

# Раз в день - полный бэкап в 03:00
0 3 * * * /opt/scripts/wp-backup-advanced.sh &gt;&gt; /var/log/wp-backup-cron.log 2&gt;&amp;1

# Раз в неделю - в облако
0 4 * * 0 /opt/scripts/wp-backup-cloud.sh &gt;&gt; /var/log/wp-backup-cron.log 2&gt;&amp;1

# ============= МОНИТОРИНГ БЭКАПОВ =============
# Проверка успешности каждый день в 12:00
0 12 * * * /opt/scripts/wp-backup-monitor.sh &gt;&gt; /var/log/wp-backup-cron.log 2&gt;&amp;1

Скрипт бэкапа только БД (для частых запусков)

#!/bin/bash
# Файл: /opt/scripts/wp-db-only-backup.sh
# Быстрый бэкап только базы данных

DB_NAME=&quot;wordpress_db&quot;
DB_USER=&quot;wp_user&quot;
DB_PASSWORD=&quot;secure_password&quot;
BACKUP_DIR=&quot;/backups/wordpress/db-only&quot;
DATE=$(date +%Y%m%d_%H%M%S)

mkdir -p &quot;$BACKUP_DIR&quot;

mysqldump \
  --user=&quot;$DB_USER&quot; \
  --password=&quot;$DB_PASSWORD&quot; \
  --single-transaction \
  --quick \
  &quot;$DB_NAME&quot; | gzip &gt; &quot;$BACKUP_DIR/db_${DATE}.sql.gz&quot;

# Оставляем только последние 48 часов
find &quot;$BACKUP_DIR&quot; -name &quot;db_*.sql.gz&quot; -type f -mmin +2880 -delete

echo &quot;$(date) - DB <a class="wpil_keyword_link" href="https://it-apteka.com/category/rezervnoe-kopirovanie/"   title="Резервное копирование" data-wpil-keyword-link="linked"  data-wpil-monitor-id="48">backup</a>: $(du -h $BACKUP_DIR/db_${DATE}.sql.gz | cut -f1)&quot;

Скрипт восстановления WordPress из бэкапа

Бэкап без восстановления — это просто архив. Вот полноценный скрипт для быстрого recovery после сбоя, взлома или переноса сайта.

#!/bin/bash
# Файл: /opt/scripts/wp-restore.sh
# Восстановление WordPress из бэкапа

set -euo pipefail

# ============= ПАРАМЕТРЫ =============
if [ $# -lt 1 ]; then
    echo &quot;Использование: $0 &lt;путь_к_бэкапу.tar.gz&gt;&quot;
    echo &quot;Пример: $0 /backups/wordpress/mysite/mysite_20240120_030000.tar.gz&quot;
    exit 1
fi

BACKUP_FILE=&quot;$1&quot;
RESTORE_TEMP=&quot;/tmp/wp-restore-$(date +%Y%m%d_%H%M%S)&quot;
WP_ROOT=&quot;/var/www/html/mysite.com&quot;

# MySQL настройки
DB_NAME=&quot;wordpress_db&quot;
DB_USER=&quot;wp_user&quot;
DB_PASSWORD=&quot;secure_password&quot;
DB_HOST=&quot;localhost&quot;

# ============= ПРОВЕРКИ =============
if [ ! -f &quot;$BACKUP_FILE&quot; ]; then
    echo &quot;ERROR: Файл бэкапа не найден: $BACKUP_FILE&quot;
    exit 1
fi

echo &quot;=========================================&quot;
echo &quot;ВОССТАНОВЛЕНИЕ WORDPRESS ИЗ БЭКАПА&quot;
echo &quot;=========================================&quot;
echo &quot;Бэкап: $BACKUP_FILE&quot;
echo &quot;Целевая директория: $WP_ROOT&quot;
echo &quot;База данных: $DB_NAME&quot;
echo &quot;&quot;
echo &quot;⚠️  ВНИМАНИЕ: Текущие файлы и БД будут ПЕРЕЗАПИСАНЫ!&quot;
echo &quot;&quot;
read -p &quot;Продолжить? (yes/no): &quot; CONFIRM

if [ &quot;$CONFIRM&quot; != &quot;yes&quot; ]; then
    echo &quot;Отменено пользователем&quot;
    exit 0
fi

# ============= РАСПАКОВКА БЭКАПА =============
echo &quot;&quot;
echo &quot;[1/5] Распаковка бэкапа...&quot;
mkdir -p &quot;$RESTORE_TEMP&quot;
tar xzf &quot;$BACKUP_FILE&quot; -C &quot;$RESTORE_TEMP&quot; --strip-components=1

# Определяем структуру бэкапа
if [ -d &quot;$RESTORE_TEMP/database&quot; ]; then
    DB_DUMP=$(find &quot;$RESTORE_TEMP/database&quot; -name &quot;*.sql.gz&quot; -o -name &quot;*.sql&quot; | head -1)
else
    DB_DUMP=$(find &quot;$RESTORE_TEMP&quot; -name &quot;*.sql.gz&quot; -o -name &quot;*.sql&quot; | head -1)
fi

if [ -z &quot;$DB_DUMP&quot; ]; then
    echo &quot;ERROR: Дамп базы данных не найден в бэкапе&quot;
    exit 1
fi

echo &quot;✓ Найден дамп БД: $(basename $DB_DUMP)&quot;

# ============= СОЗДАНИЕ РЕЗЕРВНОЙ КОПИИ ТЕКУЩЕГО СОСТОЯНИЯ =============
echo &quot;&quot;
echo &quot;[2/5] Создание резервной копии текущего состояния...&quot;
SAFETY_BACKUP=&quot;/tmp/wp-safety-backup-$(date +%Y%m%d_%H%M%S)&quot;
mkdir -p &quot;$SAFETY_BACKUP&quot;

# Бэкап текущей БД
mysqldump -u&quot;$DB_USER&quot; -p&quot;$DB_PASSWORD&quot; &quot;$DB_NAME&quot; 2&gt;/dev/null | \
    gzip &gt; &quot;$SAFETY_BACKUP/current-db.sql.gz&quot; || true

# Бэкап текущих файлов
if [ -d &quot;$WP_ROOT&quot; ]; then
    tar czf &quot;$SAFETY_BACKUP/current-files.tar.gz&quot; -C &quot;$(dirname $WP_ROOT)&quot; &quot;$(basename $WP_ROOT)&quot; 2&gt;/dev/null || true
fi

echo &quot;✓ Резервная копия создана: $SAFETY_BACKUP&quot;

# ============= ВОССТАНОВЛЕНИЕ БАЗЫ ДАННЫХ =============
echo &quot;&quot;
echo &quot;[3/5] Восстановление базы данных...&quot;

# Пересоздаём БД
mysql -u&quot;$DB_USER&quot; -p&quot;$DB_PASSWORD&quot; &lt;&lt;EOF
DROP DATABASE IF EXISTS ${DB_NAME};
CREATE DATABASE ${DB_NAME} CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
EOF

# Восстанавливаем дамп
if [[ &quot;$DB_DUMP&quot; == *.gz ]]; then
    gunzip &lt; &quot;$DB_DUMP&quot; | mysql -u&quot;$DB_USER&quot; -p&quot;$DB_PASSWORD&quot; &quot;$DB_NAME&quot;
else
    mysql -u&quot;$DB_USER&quot; -p&quot;$DB_PASSWORD&quot; &quot;$DB_NAME&quot; &lt; &quot;$DB_DUMP&quot;
fi

echo &quot;✓ База данных восстановлена&quot;

# ============= ВОССТАНОВЛЕНИЕ ФАЙЛОВ =============
echo &quot;&quot;
echo &quot;[4/5] Восстановление файлов WordPress...&quot;

# Создаём директорию если не существует
mkdir -p &quot;$WP_ROOT&quot;

# Восстанавливаем wp-content
if [ -f &quot;$RESTORE_TEMP/files/wp-content.tar.gz&quot; ]; then
    tar xzf &quot;$RESTORE_TEMP/files/wp-content.tar.gz&quot; -C &quot;$WP_ROOT&quot;
fi

# Восстанавливаем uploads отдельно (если есть)
if [ -f &quot;$RESTORE_TEMP/files/uploads.tar.gz&quot; ]; then
    mkdir -p &quot;$WP_ROOT/wp-content&quot;
    tar xzf &quot;$RESTORE_TEMP/files/uploads.tar.gz&quot; -C &quot;$WP_ROOT/wp-content&quot;
fi

# Восстанавливаем конфиги
if [ -f &quot;$RESTORE_TEMP/files/wp-config.php&quot; ]; then
    cp &quot;$RESTORE_TEMP/files/wp-config.php&quot; &quot;$WP_ROOT/&quot;
fi

if [ -f &quot;$RESTORE_TEMP/files/.htaccess&quot; ]; then
    cp &quot;$RESTORE_TEMP/files/.htaccess&quot; &quot;$WP_ROOT/&quot;
fi

echo &quot;✓ Файлы восстановлены&quot;

# ============= УСТАНОВКА ПРАВ =============
echo &quot;&quot;
echo &quot;[5/5] Установка прав доступа...&quot;

# Права для Nginx/Apache
chown -R www-data:www-data &quot;$WP_ROOT&quot;
find &quot;$WP_ROOT&quot; -type d -exec chmod 755 {} \;
find &quot;$WP_ROOT&quot; -type f -exec chmod 644 {} \;

# wp-config.php должен быть недоступен для чтения другим пользователям
chmod 640 &quot;$WP_ROOT/wp-config.php&quot;

echo &quot;✓ Права установлены&quot;

# ============= ОЧИСТКА =============
rm -rf &quot;$RESTORE_TEMP&quot;

# ============= ИТОГОВАЯ ИНФОРМАЦИЯ =============
echo &quot;&quot;
echo &quot;=========================================&quot;
echo &quot;✅ ВОССТАНОВЛЕНИЕ ЗАВЕРШЕНО&quot;
echo &quot;=========================================&quot;
echo &quot;WordPress восстановлен в: $WP_ROOT&quot;
echo &quot;База данных: $DB_NAME восстановлена&quot;
echo &quot;&quot;
echo &quot;Резервная копия старого состояния:&quot;
echo &quot;$SAFETY_BACKUP&quot;
echo &quot;&quot;
echo &quot;Рекомендации:&quot;
echo &quot;1. Проверьте работу сайта в браузере&quot;
echo &quot;2. Проверьте wp-config.php (пароли БД)&quot;
echo &quot;3. Очистите кэш (если используете плагины кэширования)&quot;
echo &quot;4. Перезапустите веб-сервер:&quot;
echo &quot;   sudo systemctl restart nginx&quot;
echo &quot;&quot;

if command -v wp &amp;&gt; /dev/null; then
    cd &quot;$WP_ROOT&quot;
    echo &quot;Проверка через WP-CLI:&quot;
    wp core verify-checksums --allow-root || true
    wp plugin list --allow-root || true
fi

Быстрое восстановление одной командой

# Делаем скрипт исполняемым
chmod +x /opt/scripts/wp-restore.sh

# Восстанавливаем из бэкапа
sudo /opt/scripts/wp-restore.sh /backups/wordpress/mysite/mysite_20240120_030000.tar.gz

# После восстановления не забудьте перезапустить веб-сервер
sudo systemctl restart nginx
# или
sudo systemctl restart apache2

Скрипт мониторинга бэкапов

Автоматический бэкап работает, но как узнать что всё в порядке? Создадим скрипт проверки с уведомлениями в Telegram.

#!/bin/bash
# Файл: /opt/scripts/wp-backup-monitor.sh
# Мониторинг состояния бэкапов WordPress

set -euo pipefail

SITE_NAME=&quot;mysite&quot;
BACKUP_ROOT=&quot;/backups/wordpress/${SITE_NAME}&quot;
TELEGRAM_BOT_TOKEN=&quot;your-token&quot;
TELEGRAM_CHAT_ID=&quot;your-chat-id&quot;
MAX_AGE_HOURS=26  # Максимум 26 часов без бэкапа

send_telegram() {
    curl -s -X POST &quot;https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendMessage&quot; \
        -d chat_id=&quot;${TELEGRAM_CHAT_ID}&quot; \
        -d parse_mode=&quot;HTML&quot; \
        -d text=&quot;$1&quot; &gt; /dev/null
}

# Поиск последнего бэкапа
LATEST_BACKUP=$(find &quot;$BACKUP_ROOT&quot; -name &quot;*.tar.gz&quot; -type f -printf &#039;%T@ %p\n&#039; | sort -rn | head -1 | cut -d&#039; &#039; -f2-)

if [ -z &quot;$LATEST_BACKUP&quot; ]; then
    send_telegram &quot;⚠️ &lt;b&gt;КРИТИЧНО&lt;/b&gt;: Бэкапы WordPress не найдены!
    
📱 Сайт: ${SITE_NAME}
🖥 Сервер: $(hostname)&quot;
    exit 1
fi

# Проверка возраста бэкапа
BACKUP_AGE_SEC=$(( $(date +%s) - $(stat -c %Y &quot;$LATEST_BACKUP&quot;) ))
BACKUP_AGE_HOURS=$(( BACKUP_AGE_SEC / 3600 ))

if [ $BACKUP_AGE_HOURS -gt $MAX_AGE_HOURS ]; then
    send_telegram &quot;⚠️ &lt;b&gt;ВНИМАНИЕ&lt;/b&gt;: Устаревший бэкап WordPress

📱 Сайт: ${SITE_NAME}
⏱ Возраст: ${BACKUP_AGE_HOURS} часов
📁 Файл: $(basename $LATEST_BACKUP)
🖥 Сервер: $(hostname)&quot;
    exit 1
fi

# Проверка размера (должен быть больше 100KB)
BACKUP_SIZE_KB=$(du -k &quot;$LATEST_BACKUP&quot; | cut -f1)
if [ $BACKUP_SIZE_KB -lt 100 ]; then
    send_telegram &quot;⚠️ &lt;b&gt;ВНИМАНИЕ&lt;/b&gt;: Подозрительно маленький размер бэкапа

📱 Сайт: ${SITE_NAME}
📏 Размер: $(du -h $LATEST_BACKUP | cut -f1)
📁 Файл: $(basename $LATEST_BACKUP)&quot;
    exit 1
fi

# Проверка целостности архива
if ! tar tzf &quot;$LATEST_BACKUP&quot; &gt; /dev/null 2&gt;&amp;1; then
    send_telegram &quot;❌ &lt;b&gt;КРИТИЧНО&lt;/b&gt;: Бэкап повреждён!

📱 Сайт: ${SITE_NAME}
📁 Файл: $(basename $LATEST_BACKUP)
🖥 Сервер: $(hostname)&quot;
    exit 1
fi

# Еженедельный отчёт (по понедельникам)
if [ &quot;$(date +%u)&quot; -eq 1 ]; then
    TOTAL_BACKUPS=$(find &quot;$BACKUP_ROOT&quot; -name &quot;*.tar.gz&quot; -type f | wc -l)
    TOTAL_SIZE=$(du -sh &quot;$BACKUP_ROOT&quot; | cut -f1)
    OLDEST_BACKUP=$(find &quot;$BACKUP_ROOT&quot; -name &quot;*.tar.gz&quot; -type f -printf &#039;%T@ %p\n&#039; | sort -n | head -1 | cut -d&#039; &#039; -f2-)
    OLDEST_DATE=$(date -r &quot;$OLDEST_BACKUP&quot; &quot;+%d.%m.%Y&quot;)
    
    send_telegram &quot;✅ &lt;b&gt;Еженедельный отчёт - WordPress бэкапы&lt;/b&gt;

📱 Сайт: ${SITE_NAME}
📦 Всего бэкапов: ${TOTAL_BACKUPS}
💾 Общий размер: ${TOTAL_SIZE}

🆕 Последний: $(basename $LATEST_BACKUP)
📏 Размер: $(du -h $LATEST_BACKUP | cut -f1)
⏱ Создан: ${BACKUP_AGE_HOURS}ч назад

📅 Самый старый: ${OLDEST_DATE}
🖥 Сервер: $(hostname)&quot;
fi

exit 0

Best Practices: чек-лист профессионала

1. Правило 3-2-1 для WordPress

  • 3 копии данных: Production + локальный бэкап + облачный бэкап
  • 2 разных носителя: SSD сервера + внешний HDD или S3
  • 1 копия offsite: AWS S3, Backblaze B2, Google Drive или удалённый сервер

2. Что НЕ нужно бэкапить

# Исключения для экономии места и времени
--exclude=&#039;wp-content/cache/*&#039;           # Кэш плагинов
--exclude=&#039;wp-content/w3tc-config/*&#039;     # W3 Total Cache
--exclude=&#039;wp-content/backup-*&#039;          # Старые бэкапы плагинов
--exclude=&#039;wp-content/ai1wm-backups/*&#039;   # All-in-One WP Migration
--exclude=&#039;wp-content/updraft/*&#039;         # UpdraftPlus бэкапы
--exclude=&#039;*.log&#039;                         # Лог-файлы
--exclude=&#039;*.tmp&#039;                         # Временные файлы
--exclude=&#039;wp-content/debug.log&#039;          # Debug лог WordPress

3. Тестируйте восстановление регулярно

#!/bin/bash
# Ежемесячный тест восстановления в изолированном окружении

# Создаём тестовую директорию
TEST_DIR=&quot;/var/www/test-restore&quot;
mkdir -p &quot;$TEST_DIR&quot;

# Восстанавливаем последний бэкап
LATEST_BACKUP=$(find /backups/wordpress/mysite -name &quot;*.tar.gz&quot; | sort -r | head -1)
tar xzf &quot;$LATEST_BACKUP&quot; -C &quot;$TEST_DIR&quot;

# Проверяем целостность
if [ -f &quot;$TEST_DIR/files/wp-config.php&quot; ] &amp;&amp; [ -f &quot;$TEST_DIR/database/*.sql.gz&quot; ]; then
    echo &quot;✓ Тест восстановления пройден&quot;
    # Отправляем уведомление об успехе
else
    echo &quot;✗ ОШИБКА: Бэкап некорректен!&quot;
    # Отправляем алерт
fi

# Очистка
rm -rf &quot;$TEST_DIR&quot;

4. Защита бэкапов

# Шифрование бэкапа перед отправкой в облако
#!/bin/bash

BACKUP_FILE=&quot;/backups/wordpress/mysite_backup.tar.gz&quot;
ENCRYPTED_FILE=&quot;${BACKUP_FILE}.gpg&quot;
GPG_RECIPIENT=&quot;admin@example.com&quot;

# Шифрование
gpg --encrypt --recipient &quot;$GPG_RECIPIENT&quot; &quot;$BACKUP_FILE&quot;

# Отправка зашифрованного файла
aws s3 cp &quot;$ENCRYPTED_FILE&quot; s3://my-backups/

# Расшифровка при восстановлении
gpg --decrypt &quot;${ENCRYPTED_FILE}&quot; &gt; &quot;$BACKUP_FILE&quot;

Таблица стратегий бэкапа WordPress

Тип сайта Частота бэкапа Хранение Рекомендуемый скрипт
Личный блог 1 раз в день Локально 30 дней wp-backup-basic.sh
Корпоративный сайт 2 раза в день Локально + S3 wp-backup-advanced.sh
Новостной портал Каждые 6 часов Локально + облако wp-backup-wpcli.sh
Интернет-магазин БД каждые 4ч + полный раз в день Множественные копии wp-backup-cloud.sh
Высоконагруженный Непрерывный (каждый час) S3 + реплика БД Профессиональные решения

Типичные ошибки и как их избежать

Ошибка 1: Бэкап только БД или только файлов

Я видел десятки случаев, когда админы бэкапили только базу данных, забывая про загруженные файлы (изображения, документы). Или наоборот — архивировали wp-content, но не делали дамп БД. Результат: невозможность полного восстановления.

Решение: Всегда бэкапьте И базу данных, И файлы в одном процессе.

Ошибка 2: Хранение бэкапов в wp-content/backups

Некоторые плагины бэкапа по умолчанию сохраняют архивы прямо в wp-content/backups. Это катастрофа для безопасности — бэкапы доступны через веб! Хакер может скачать весь сайт вместе с паролями.

# ПЛОХО - бэкапы доступны через браузер
/var/www/html/wp-content/backups/backup.tar.gz
# Доступно по https://site.com/wp-content/backups/backup.tar.gz

# ХОРОШО - бэкапы вне веб-директории
/backups/wordpress/backup.tar.gz
# Недоступно через браузер

Ошибка 3: Бэкап без проверки восстановления

Бэкап, который никогда не тестировали на восстановление — это бомба замедленного действия. Возможно, в архиве нет критичных файлов, или дамп БД повреждён.

# Скрипт автоматической проверки целостности бэкапа
#!/bin/bash

LATEST_BACKUP=$(find /backups/wordpress/mysite -name &quot;*.tar.gz&quot; | sort -r | head -1)

# Проверка архива
if tar tzf &quot;$LATEST_BACKUP&quot; | grep -q &quot;wp-config.php&quot;; then
    echo &quot;✓ wp-config.php найден в архиве&quot;
else
    echo &quot;✗ ОШИБКА: wp-config.php отсутствует!&quot;
    # Отправить алерт
fi

# Проверка дампа БД
if tar tzf &quot;$LATEST_BACKUP&quot; | grep -q &quot;\.sql&quot;; then
    echo &quot;✓ Дамп БД найден&quot;
else
    echo &quot;✗ ОШИБКА: Дамп БД отсутствует!&quot;
fi

Заключение: моя стратегия бэкапа WordPress в 2025

За 20 лет администрирования WordPress сайтов (от личных блогов до порталов с миллионами просмотров) я выработал универсальную стратегию, которая никогда не подводила:

Для личных блогов и малого бизнеса:

  • Базовый скрипт каждый день в 02:00
  • Хранение 30 дней локально
  • Еженедельная отправка в облако (S3/B2)
  • Ежемесячный тест восстановления

Для корпоративных сайтов и порталов:

  • Полный бэкап 2 раза в день
  • Дамп БД каждые 6 часов
  • Локально 7 дней + облако 90 дней
  • Мониторинг с уведомлениями в Telegram
  • Автоматический тест восстановления раз в неделю

Для интернет-магазинов (WooCommerce):

  • БД каждые 4 часа (заказы критичны!)
  • Полный бэкап раз в день
  • Множественные копии: локально + S3 + второй сервер
  • Реплика БД в реальном времени
  • Дневной мониторинг

Три железных правила бэкапа WordPress:

  1. Автоматизация обязательна — люди забывают, cron не забывает никогда
  2. Тестируйте восстановление — минимум раз в месяц проверяйте, что бэкап рабочий
  3. Offsite копия критична — локальный бэкап не спасёт при пожаре сервера

Настройте бэкапы правильно один раз, и спите спокойно. Потеря WordPress сайта — это не конец света, если у вас есть свежий бэкап. А вот потеря сайта БЕЗ бэкапа — это катастрофа, которую я не пожелаю даже врагу.

P.S. Помните: лучший бэкап — тот, который сделан ДО того, как что-то сломалось. Не откладывайте настройку на потом!

Поделитесь:

Оставьте комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Прокрутить вверх