Резервная копия сайта WordPress: ошибки новичков
На выходе — SQL-дамп базы и архив wp-content, лежащие вне сервера сайта, плюс проверка, что из них поднимается рабочая копия. Первый раз займёт 30-40 минут, дальше всё делает cron.

Результат, к которому идём: два файла — SQL-дамп базы и архив wp-content вместе с wp-config.php — лежат не на том сервере, где работает сайт, и вы своими руками проверили, что из них поднимается живая копия. Первый проход занимает 30-40 минут на сайте с парой гигабайт медиа. Дальше это делает cron, а вы раз в квартал проверяете разворот. Инструкция написана для WordPress 6.x, WP-CLI 2.x, MySQL 8.0 или MariaDB 10.x на обычном Linux-хостинге с SSH.
Что нужно иметь до начала
- Доступ по SSH к аккаунту хостинга. Если его нет — смотрите раздел «Если SSH нет», но проверить копию всё равно придётся вручную.
- WP-CLI на сервере. Проверяется одной командой:
wp --info. Должны увидеть версию PHP и строку с версией WP-CLI. Если команды нет — у многих хостингов она ставится в один клик в панели или доступна какwp-cli.phar. - Данные базы из
wp-config.php:DB_NAME,DB_USER,DB_HOST. Открывать файл не обязательно, WP-CLI читает их сам, но для ручного пути они понадобятся. - Свободное место на диске — не меньше размера
wp-contentплюс размер базы. Копия, упавшая на середине из-за квоты, хуже отсутствия копии: она выглядит как файл. - Место, где копия будет лежать: ваш компьютер, внешний диск, объектное хранилище. Любое, кроме каталога внутри сайта.
Что входит в копию, а что нет
Самая частая ошибка новичка — скопировать файлы и забыть базу. В файлах нет ни одного вашего текста: записи, страницы, товары, настройки, пользователи и комментарии живут в MySQL. Обратная ошибка такая же: дамп базы без uploads даст сайт со всеми текстами и битыми картинками.
| Что | Где лежит | В копию | Почему так |
|---|---|---|---|
| База данных, все таблицы с вашим префиксом | MySQL / MariaDB | Да | Записи, настройки, пользователи, заказы |
| Медиафайлы | wp-content/uploads | Да | Больше нигде не хранятся |
| Темы и плагины | wp-content/themes, wp-content/plugins | Да | Правки в дочерней теме и конкретные версии плагинов |
| Конфиг и правила сервера | wp-config.php, .htaccess в корне | Да | Префикс таблиц, соли, редиректы |
| Ядро | wp-admin, wp-includes, корневые php-файлы | Нет | Качается заново, достаточно записать номер версии |
| Кеш, временные каталоги, архивы плагинов-бэкаперов | wp-content/cache, wp-content/upgrade, папки бэкап-плагинов | Нет | Мусор и рекурсия: копия внутри копии раздувает архив вдвое |
SQL-дамп — обычный текстовый файл с командами SQL: создать таблицу, вставить такие-то строки. Его можно открыть редактором и прочитать. Именно поэтому дамп сжимается в 5-10 раз и именно поэтому его нельзя править поиском с заменой: часть значений в базе WordPress хранится в сериализованном виде, где длина строки указана числом рядом с ней.
Шесть шагов
-
Узнайте объёмы. Подставьте свой путь к сайту.
cd /var/www/example.ru du -sh wp-content wp-content/uploads wp db size --human-readableПроверка: видите три строки с размерами. Если
wp db sizeв вашей сборке не принимает--human-readable, запустите её без флага — получите размер в байтах. Сумма размеров и есть то место, которое нужно найти в хранилище. -
Снимите дамп базы.
mkdir -p ~/backups wp db export ~/backups/db-$(date +%F).sql --add-drop-table --single-transaction ls -lh ~/backups/ tail -n 2 ~/backups/db-$(date +%F).sqlПроверка: в конце файла есть строка-комментарий
-- Dump completed onс датой. Нет её — дамп обрезан, повторите. Флаги--add-drop-tableи--single-transactionWP-CLI передаёт вmysqldump: первый позволит залить дамп в непустую базу, второй снимает слепок без блокировки таблиц InnoDB. -
Упакуйте файлы. Пароли и ключи в командах не нужны, всё берётся из конфига.
cd /var/www/example.ru tar -czf ~/backups/files-$(date +%F).tar.gz \ --exclude='wp-content/cache' \ --exclude='wp-content/upgrade' \ --exclude='wp-content/backups' \ wp-content wp-config.php .htaccessПроверка:
tar -tzf ~/backups/files-$(date +%F).tar.gz | headпоказывает пути, начинающиеся сwp-content/, аgzip -tна этом файле молчит. Если сайт работает на nginx,.htaccessиз списка уберите, иначе tar отдаст ошибку о несуществующем файле. -
Унесите копию с сервера. Команда запускается на вашем компьютере, не на хостинге.
mkdir -p ~/wp-backups rsync -avz YOUR_SSH_USER@example.ru:~/backups/ ~/wp-backups/ shasum -a 256 ~/wp-backups/files-*.tar.gzПроверка: сравните хеш с тем, что выдаёт
sha256sumна сервере. Совпали — файл доехал целиком. Копия, оставшаяся на том же диске, не спасёт ни от удаления аккаунта за неоплату, ни от взлома, при котором злоумышленник чистит и бэкапы. -
Разверните копию и убедитесь, что она живая. На локальной машине или тестовом поддомене поставьте чистый WordPress той же версии, распакуйте архив поверх и залейте дамп.
mysql -u YOUR_DB_USER -p -e 'CREATE DATABASE wp_restore_test CHARACTER SET utf8mb4;' # в wp-config.php тестовой копии укажите базу wp_restore_test wp db import ~/wp-backups/db-2025-06-01.sql wp search-replace 'https://example.ru' 'http://example.local' --all-tables-with-prefix --dry-runПроверка:
wp db importзаканчивается строкой об успешном импорте,--dry-runпоказывает количество найденных замен по таблицам. Уберите--dry-run, откройте тестовый адрес, зайдите в админку, посмотрите список записей и последние загруженные картинки. Только теперь у вас есть резервная копия. -
Поставьте это на расписание. Скрипт
~/scripts/wp-backup.sh:#!/bin/bash set -euo pipefail SITE=/var/www/example.ru DEST=/home/YOUR_SSH_USER/backups STAMP=$(date +%F-%H%M) mkdir -p "$DEST" wp --path="$SITE" db export "$DEST/db-$STAMP.sql" gzip -f "$DEST/db-$STAMP.sql" tar -czf "$DEST/files-$STAMP.tar.gz" -C "$SITE" \ --exclude='wp-content/cache' \ --exclude='wp-content/upgrade' \ wp-content wp-config.php # держим копии за неделю find "$DEST" -name '*.gz' -mtime +7 -deleteДальше
chmod +x ~/scripts/wp-backup.shи строка вcrontab -e:15 4 * * * /home/YOUR_SSH_USER/scripts/wp-backup.sh >> /home/YOUR_SSH_USER/backup.log 2>&1Проверка: на следующее утро в каталоге лежат два файла со свежей датой, а
backup.logпустой. Непустой лог — читайте его, там написана причина. Выгрузку в хранилище добавьте в конец скрипта тем жеrsyncпо ключу без пароля.
Если SSH нет
Порядок тот же, меняются инструменты. База: phpMyAdmin в панели хостинга, вкладка «Экспорт», формат SQL, сжатие gzip — скачанный файл должен быть не «0 байт» и не 1 КБ. Файлы: архив wp-content и wp-config.php через файловый менеджер панели, затем скачать. Либо плагин-бэкапер вроде UpdraftPlus или All-in-One WP Migration с выгрузкой в облако — у обоих есть бесплатные версии с ограничениями, и у обоих есть общая засада: расписание они вешают на WP-Cron, который на сайте без посетителей просто не запускается. Если копий по расписанию нет неделями, причина чаще всего эта: отключите WP-Cron константой DISABLE_WP_CRON и дёргайте wp-cron.php системным cron хостинга.
Копия, которую ни разу не разворачивали, — это не копия, а файл неизвестного содержания. Узнать, что в нём, вы успеете только в тот день, когда уже ничего другого не осталось.
Если не получилось
mysqldump: command not foundили WP-CLI жалуется, что не нашёл mysqldump. На части шаред-хостингов клиентские утилиты MySQL недоступны. Выход: экспорт через phpMyAdmin или плагин, который работает средствами PHP.Error: This does not seem to be a WordPress installation.Вы запустилиwpне из каталога сайта. Перейдите в корень, где лежитwp-config.php, или добавьте--path=/var/www/example.ru— в скрипте для cron это обязательно, у cron нет вашего текущего каталога.Error establishing a database connectionпосле разворота копии. Вwp-config.phpостались данные боевой базы: имя базы, пользователь,DB_HOST. Для тестовой копии правьте их вручную, вlocalhostпротив127.0.0.1:3306тоже упираются регулярно.No space left on deviceили архив вдруг весит столько же, сколько весь аккаунт. Почти всегда это папка бэкап-плагина внутриwp-content: вы пакуете старые архивы в новый архив. Добавьте её в--excludeи удалите то, что уже уехало в хранилище.MySQL server has gone awayпри импорте большого дампа. Обрывается соединение из-за лимитаmax_allowed_packetна сервере, куда вы заливаете. Либо поднимите лимит там, где к нему есть доступ, либо импортируйте через консоль, а не через phpMyAdmin с его ограничением на размер загружаемого файла.- Белый экран или вёрстка без картинок после разворота на другом адресе. Домен меняли запросом
UPDATEили поиском с заменой в .sql — сериализованные значения вwp_optionsсломались. Делайте только черезwp search-replace, он пересчитывает длины строк.
Что делать дальше
Привяжите частоту копий к тому, сколько работы вы готовы потерять: блог с парой постов в неделю переживёт суточную копию, магазин с заказами — нет, ему нужны и ежедневный дамп, и бинлоги на стороне хостинга. Отдельно поставьте копию перед каждым обновлением ядра и плагинов — не после, когда сайт уже лежит. Запишите в текстовый файл рядом с архивами версию WordPress, версию PHP и порядок разворота в пяти строках: в стрессовой ситуации вы не будете вспоминать флаги. Раз в квартал поднимайте копию на тестовом поддомене и смотрите на два показателя: размер свежих файлов относительно прошлой недели и дату последнего успешного разворота. Если размер дампа внезапно упал вдвое — что-то уже сломалось, и лучше узнать об этом сейчас.
Проверка рекламы на риски: Что в макете вызовет вопросы ФАС: превосходные степени, сравнения, обещания результата, маркировка.
Спросить за 40 ₽Источники: WordPress Backups — документация WordPress, WP-CLI: wp db export
Частые вопросы
Хостинг и так делает бэкапы. Зачем своя копия?
У меня WordPress 5.x и нет WP-CLI, инструкция подойдёт?
Нужно ли копировать wp-admin и wp-includes?
Снимать копию на работающем сайте — не положит ли это базу?
Можно ли хранить архивы в wp-content/uploads, чтобы скачивать по ссылке?
Как понять, что копия годная, не разворачивая весь сайт?
Материал носит информационный характер и подготовлен редакцией «Агентуры». Он не является офертой, рекламой или индивидуальной консультацией. Упомянутые продукты, компании и торговые знаки принадлежат их правообладателям. Перед принятием решений, влекущих юридические или финансовые последствия, обратитесь к профильному специалисту.