WP Manifestindependent plugin directory
manifest / updates / easy-site-backup

Easy Site Backup

Простий плагін для WordPress для резервного копіювання бази даних і файлів

★ 0stars

Install

Download source zip No release zip yet

This is the repository archive. It installs, but the folder name will carry the branch suffix and updates will not flow.

Install straight from GitHub with WP-CLI:

wp plugin install https://github.com/eugene88-source/easy-site-backup/archive/refs/heads/main.zip
Updates itself. It ships its own updater, so new versions appear under Dashboard → Updates.

Простий плагін для WordPress для резервного копіювання бази даних і файлів

Можливості

  • Сторінка Інструменти → Easy Site Backup в адмінці.
  • Три типи копій: база даних + файли, тільки база даних, тільки файли.
  • Кожна копія — один ZIP-архів.
  • Покрокове створення: кожен крок триває до 20 секунд, тож бекап не впирається в max_execution_time і таймаут Cloudflare (100 с).
  • Прогрес-бар і скасування. Якщо закрити сторінку, копіювання продовжиться у фоні через WP-Cron.
  • Перерваний крок (таймаут, обрив зв'язку) повторюється з того самого місця.
  • Список копій із завантаженням, відновленням, логом і видаленням — по одній або кількох вибраних одразу.

Розклад

У блоці Розклад на сторінці плагіна можна ввімкнути автоматичні копії: щодня або щотижня в заданий час (за часовим поясом сайту), будь-якого з трьох типів.

  • Зберігаються лише останні N копій за розкладом (типово 5); старіші видаляються після кожної нової. Копії, створені вручну, не видаляються. Невдалі копії за розкладом прибираються через 30 днів.
  • Лист на пошту — лише про помилки (типово), після кожної копії або ніколи. Адреса — адміністратора сайту або вказана; лог копії додається вкладенням.
  • Якщо в момент запуску вже створюється копія чи йде відновлення, запуск пропускається з листом про помилку.
  • WP-Cron спрацьовує лише під час відвідування сайту. Для точного часу вимкніть його в wp-config.php (define( 'DISABLE_WP_CRON', true );) і запускайте системним cron щохвилини: * * * * * curl -s https://example.com/wp-cron.php > /dev/null

Відновлення

Кнопка Відновити в списку копій повертає сайт до стану копії: базу даних і файли — те, що є в копії. Відновлення також іде кроками з прогрес-баром і продовжується через WP-Cron, якщо закрити сторінку. Скасувати його не можна.

  • База даних спершу імпортується в тимчасові таблиці esbr_…, а наприкінці одним RENAME TABLE замінює робочі. Якщо відновлення зламається раніше, база сайту лишиться без змін.
  • Якщо хостинг обірве крок (ліміт часу чи пам'яті, перезапуск), наступний продовжить з місця обриву. Інструкцію, яка встигла виконатися, але не потрапила в збережений стан, відновлення розпізнає за кількістю рядків і не повторює — навіть у таблицях без ключа; іменоване блокування MySQL гарантує, що запит обірваного кроку вже завершився. Після трьох обривів поспіль — зрозуміла помилка, база без змін. Перевірено тестом, що вбиває процес у випадкові моменти.
  • Кожен файл розпаковується поруч і лише потім замінює наявний; цілісність перевіряється за CRC.
  • Не відновлюються: wp-config.php, сам плагін і тека з копіями.
  • Файли й таблиці, яких немає в копії, не видаляються.
  • Відновити можна лише на той самий сайт: адреса й префікс таблиць мають збігатися. Перенесення між сайтами поки не підтримується.
  • Якщо після створення копії ви входили заново, після відновлення може знадобитися увійти ще раз.
  • Хід і результат відновлення записуються в лог копії.

Відновлення з файлу

Якщо сайт зламаний чи сервер втрачено, відновити можна з архіву, завантаженого раніше на комп'ютер:

  1. Встановіть чистий WordPress з тією самою адресою сайту й тим самим префіксом таблиць ($table_prefix у wp-config.php).
  2. Встановіть і активуйте Easy Site Backup.
  3. На сторінці плагіна в розділі «Наявні резервні копії» виберіть архів і натисніть Завантажити архів.
  4. Біля завантаженої копії натисніть Відновити.
  • Архів надсилається частинами до 8 МБ (менше, якщо сервер обмежує розмір запиту), тож його розмір не впирається в upload_max_filesize і ліміт Cloudflare. Обірвана частина надсилається повторно.
  • Сервер перевіряє, що це копія Easy Site Backup (manifest.json), а цілісність файлів — під час відновлення за CRC.
  • У списку завантажена копія має дату створення самої копії й позначку «завантажено з комп'ютера».
  • Після відновлення потрібно увійти з логіном і паролем, що були на сайті в момент створення копії.

Вміст архіву

Шлях в архіві Що всередині
database-001.sql, database-002.sql… Дамп усіх таблиць з префіксом WordPress, частинами по ~16 МБ (архіви до 0.5.1 — одним database.sql, вони теж відновлюються)
files/… Файли сайту відносно кореня WordPress
manifest.json Версії WP і плагіна, URL сайту, префікс таблиць, кількість файлів

Як працює

Кожна копія — окрема тека з випадковою назвою в wp-content/uploads/esb-backups/: backup.zip, log.txt (журнал) і job.json (службовий стан).

Фази: підготовка → дамп БД → додавання БД в архів → пошук файлів → архівування файлів → завершення.

  • Таблиці читаються порціями по 500 рядків, за первинним ключем, якщо він цілочисельний.
  • Жодна операція не триває довше за крок, хоч якою великою є база чи файл: дамп пишеться й відновлюється частинами по ~16 МБ, а файли від 64 МБ копіюються в архів і з архіву частинами з продовженням у наступному кроці (контрольна сума CRC частин поєднується). Неподільні фази — пошук файлів, перевірка архіву, завершення — починаються лише на початку кроку. Перевірено на хостингу з 0,1 ядра процесора й жорстким обмеженням запиту 30 с.
  • ZIP пишеться власним кодом, який лише дописує в кінець файлу: ZipArchive при кожному відкритті переписує весь архів, що для покрокового бекапу надто повільно. Якщо крок перервався, архів обрізається до стану після останнього збереженого кроку.
  • Архіви понад 4 ГБ і понад 65 535 файлів записуються у форматі ZIP64.
  • Зображення, відео, архіви й файли понад 64 МБ додаються без стиснення.
  • Файл, який не вдалося прочитати (наприклад, заблокований), пропускається із записом у лог.
  • Не потрапляють у копію: тека з бекапами, wp-content/cache, wp-content/upgrade і теки бекапів деяких інших плагінів, символьні посилання.

Оновлення

Плагін оновлюється з GitHub Releases цього репозиторію, як звичайний плагін з wordpress.org: WordPress показує нову версію на сторінці «Плагіни» і встановлює її автоматично.

  • Перевірка — щогодини через WP-Cron: нова версія встановлюється автоматично приблизно протягом години після релізу (на сайтах з малим трафіком — після найближчого відвідування). Кнопка «Перевірити знову» на сторінці оновлень перевіряє одразу.
  • Автооновлення вмикається один раз після встановлення; його можна вимкнути на сторінці «Плагіни», і плагін його знову не ввімкне. Тоді оновлення — кнопкою «Оновити».
  • Поки створюється резервна копія чи йде відновлення, автооновлення відкладається.
  • Пакет оновлення приймається лише з адрес цього репозиторію на GitHub.

Як випустити нову версію

  1. Підняти версію в easy-site-backup.php — і в заголовку Version:, і в константі ESB_VERSION.
  2. Додати в README розділ ### <версія> у «Зміни» — це буде текст релізу (WordPress показує його як список змін).
  3. Закомітити й запушити.
  4. Створити й запушити тег: git tag v0.4.0 && git push origin v0.4.0.
  5. GitHub Action Release перевірить, що тег збігається з версією, збере easy-site-backup.zip і опублікує реліз. Якщо реліз із цим тегом створено вручну, архів додасться до нього.

Безпека

  • Усі дії доступні лише користувачам із правом manage_options і захищені nonce.
  • Тека сховища захищена .htaccess та index.php, назви тек копій випадкові.
  • Жоден файл у сховищі не має постійної адреси: архіви й розпакований під час відновлення дамп бази лежать у теках копій з випадковими назвами, стан відновлення — у файлі з випадковою назвою.
  • Завантаження йде через PHP, а не за прямим посиланням. Сервер підтримує докачування (HTTP Range), а кнопка «Завантажити» в Chrome і Edge качає архів частинами по 8 МБ прямо у вибраний файл — так великий архів скачується й на хостингах, які обривають довгий запит (PHP-FPM з request_terminate_timeout). В інших браузерах — звичайне скачування, яке можна докачати.
  • На Nginx .htaccess не працює. Плагін сам перевіряє, чи віддає вебсервер файли з теки сховища (раз на добу, тестовим файлом), і якщо так — показує на своїй сторінці попередження з готовим блоком для конфігурації:
    location ^~ "/wp-content/uploads/esb-backups/" {
        deny all;
    }
  • На Apache з AllowOverride None .htaccess теж не діє — попередження з'явиться й там.

Тести

GitHub Action Tests запускається на кожен push у main, на pull request і перед кожним релізом — реліз не публікується, якщо тести не пройшли.

  • tests/unit/zip.php — запис і читання ZIP без WordPress (PHP 7.4, 8.1, 8.3).
  • tests/integration/*.php — на справжньому WordPress з MySQL (PHP 7.4, 8.3): сторінка плагіна, перевірка місця, розклад, повний цикл бекапу й відновлення.

Локально (лише на тестовому сайті — тести створюють і відновлюють копії):

php tests/unit/zip.php
php tests/integration/backup-restore.php /шлях/до/wordpress

Інтеграційним тестам потрібен активний плагін і доступний сайт (відновлення йде HTTP-запитами до admin-ajax.php).

Вимоги

  • WordPress 5.8+, PHP 7.4+
  • PHP-розширення zlib
  • На 32-бітному PHP архів не може перевищувати 2 ГБ.
  • Вільне місце перевіряється перед бекапом (з запасом на обсяг усіх файлів) і перед відновленням (дамп бази + найбільший файл). Місце під тимчасові таблиці MySQL під час відновлення не перевіряється — дані MySQL можуть лежати на іншому диску.

Зміни

1.0.0

Перша стабільна версія: повний цикл «бекап → скачати → відновити на новому сервері» перевірено на хостингах Apache + mod_php і Nginx + PHP-FPM з лімітами дешевого хостингу (128 МБ пам'яті, 30 с на запит, 0,1 ядра процесора) на сайті з базою ~600 МБ і файлом 1 ГБ, з обривами процесу у випадкові моменти.

  • Резервні копії бази й файлів вручну та за розкладом, з ротацією й листами про помилки.
  • Відновлення з копії на сервері або з архіву, завантаженого з комп'ютера; атомарна заміна бази, перевірка цілісності за CRC.
  • Покрокова робота без упирання в ліміти хостингу: дамп і великі файли частинами, скачування й завантаження архіву частинами, продовження після обірваного кроку.
  • Захищене сховище з самоперевіркою доступу на Nginx; оновлення з GitHub.

0.5.3

  • Відновлення після обірваного кроку більше не може задвоїти рядки: інструкція, що встигла виконатися до обриву, розпізнається за кількістю рядків (раніше таблиці без первинного ключа отримували дублі), а наступний крок чекає, доки MySQL завершить запит обірваного.
  • Великий файл, відновлення якого обірвалося одразу після перейменування тимчасового файлу, більше не може бути пошкоджений: якщо тимчасового файлу вже немає або він коротший за збережену позицію, файл відновлюється спочатку.
  • Новий тест «вбиває» процес PHP у випадкові моменти бекапу й відновлення (зокрема одразу після заміни таблиць) і перевіряє, що дані збігаються до байта.

0.5.2

  • Скачування великих архівів на хостингах, що обривають довгий запит: кнопка «Завантажити» в Chrome і Edge качає архів частинами по 8 МБ у вибраний файл; сервер підтримує докачування (HTTP Range) для інших браузерів, менеджерів завантажень і curl -C -.

0.5.1

  • Великі сайти на повільному хостингу: дамп бази пишеться в архів і відновлюється частинами по ~16 МБ, а файли від 64 МБ копіюються частинами між кроками, тож жоден запит не впирається в ліміт часу хостингу, хоч якою великою є база чи файл. Архіви попередніх версій відновлюються, як і раніше.
  • Неподільні фази починаються лише на початку кроку, щоб мати весь його час.
  • На Windows-серверах: повторні спроби збереження стану, якщо файл на мить зайнятий антивірусом; відхилений архів більше не лишає файлів на диску.

0.5.0

  • Відновлення з файлу: архів копії можна завантажити з комп'ютера (частинами, без обмеження розміру одного запиту) і відновити з нього сайт — зокрема на щойно встановленому WordPress після втрати сервера.

0.4.9

  • Щогодинна перевірка оновлень завжди питає GitHub наново, а не бере збережену відповідь: раніше відповідь, збережена перед самим релізом, могла ховати нову версію ще до 50 хвилин.

0.4.8

  • Блок конфігурації Nginx у попередженні: шлях у лапках (пробіл у шляху більше не ламає конфігурацію) і розкодований з URL; якщо файли uploads віддаються з іншої адреси (CDN), показується підказка, де додати блок.
  • Рядки блоку коду більше не зсуваються: прибрано відступ і зменшений шрифт, які WordPress дає тегу code.

0.4.7

  • Блок конфігурації Nginx у попередженні про відкриту теку копій показується рівним сірим прямокутником, без окремих смужок під кожним рядком.

0.4.6

  • Безпека на Nginx: розпакований під час відновлення дамп бази більше не лежить у корені сховища під постійною назвою (його можна було завантажити за відомою адресою), а стан відновлення зберігається під випадковою назвою.
  • Самоперевірка: якщо вебсервер віддає файли з теки копій напряму, на сторінці плагіна з'являється попередження з готовим блоком конфігурації Nginx.

0.4.5

  • Повернуто автоматичні оновлення: нова версія встановлюється сама приблизно протягом години після релізу. Вимкнути можна на сторінці «Плагіни».
  • Посилання «Налаштування» в рядку плагіна на сторінці «Плагіни» веде на сторінку Easy Site Backup.

0.4.4

  • Автооновлення плагіна вимкнене: нова версія з'являється на сторінці «Плагіни» приблизно протягом години, а встановлюється кнопкою «Оновити» за вашим бажанням. Автооновлення, увімкнене попередніми версіями, вимикається; за бажанням його можна ввімкнути на сторінці «Плагіни».

0.4.3

  • Список копій тепер вище за розклад; після збереження розкладу сторінка відкривається одразу на ньому, разом із повідомленням «Розклад збережено».

0.4.2

  • Оновлення плагіна перевіряються щогодини й встановлюються автоматично приблизно протягом години після релізу (раніше — до 12 годин).

0.4.1

  • Новий вигляд сторінки плагіна: кольорова шапка в тон схемі адмінки й розділи в окремих картках.

0.4.0

  • Відновлення сайту з резервної копії: атомарна заміна бази через тимчасові таблиці, перевірка цілісності файлів за CRC.
  • Бекапи за розкладом (щодня або щотижня), зберігання останніх N копій, листи про помилки.
  • Дати на сторінці плагіна показуються за часом браузера; у лозі — час сайту з позначкою поясу.
  • Перевірка вільного місця на диску перед бекапом і відновленням.