«Коли мені кажуть, що WordPress — це тільки для сайтів, я показую свій CI/CD»
WordPress як CI/CD: так, я серйозно
Кінець 2014 року, зима. Я прийшов як WordPress-розробник у волонтерський проєкт — і там вперше зіткнувся з використанням Beanstalk. Push в репо — файли на сервері. Без FTP, без ручного копіювання. Для мене тоді це було магією.
З того моменту Beanstalk став частиною мого робочого процесу. Понад десять років — без нарікань. Він просто працював.
Але коли кількість проєктів зросла — клієнтські сайти, власні продукти, пет-проєкти — я почав рахувати. Ще одна щомісячна підписка на зовнішній сервіс — і все це заради однієї простої операції: перенести файли з репозиторію на хостинг. Це як тримати штатного кур’єра, який щодня переносить одну коробку через дорогу.
Це змусило подивитися на WordPress інакше. По суті, все для побудови власного Beanstalk — уже є у WordPress.
Чому «правильні» CI/CD-інструменти не підходять
Перше, що скаже будь-який DevOps: «GitHub Actions + Docker + rsync». Красива схема. На папері.
А тепер реальність: shared-хостинг. Хостинг Україна. Тут немає Docker. Немає можливості встановлювати пакети. Немає systemd для сервісів. SSH є, але обмежений — ніякого root. GitHub Actions може зібрати проєкт, але як доставити файли на сервер без повноцінного rsync чи SCP?
Jenkins? Окремий сервер, який треба орендувати, налаштувати і підтримувати. Deployer? Потребує SSH з ключами та повноцінне CLI-середовище. Все це — додаткова інфраструктура і додаткові витрати заради однієї задачі.
Можна було взяти VPS під CI/CD. Але це як орендувати гараж, щоб зберігати один гайковий ключ.
WordPress — не CMS, а application framework
Ця думка визріла не за один день. Але коли працюєш з WordPress сімнадцять років — починаєш бачити його не як CMS для сайтів, а як платформу з повноцінним набором інструментів:
- Custom Post Types — структури даних для будь-чого
- ACF PRO — побудова інтерфейсів без написання HTML-форм
- REST API — інтеграція з будь-яким зовнішнім сервісом
- WP-Cron — відкладені та регулярні задачі
- Адмін-панель — готовий UI з авторизацією, пошуком, фільтрацією
Ідея оформилась просто: кожен деплой — це запис у WordPress. Custom Post Type з полями: звідки (репозиторій + гілка), куди (сайт на хостингу). Створюєш запис — система сама реєструє webhook на GitHub. Push — файли на сервері. Видаляєш запис — webhook зникає. Нуль ручної роботи.
Система з’єднана по API з GitHub і Хостинг Україна — репозиторії, гілки та сайти підтягуються автоматично.
Що під капотом
Стек мінімальний, але кожен елемент на своєму місці:
- WordPress — ядро системи, зберігання даних, UI
- ACF PRO + Timber/Twig — кастомні поля та шаблони адмін-панелі
- GitHub API — управління вебхуками, список репозиторіїв і гілок
- Хостинг Україна API (adm.tools) — список сайтів із шляхами до директорій
- Telegram Bot API — нотифікації про статус деплою
Два кастомних ACF-поля, які вирішують UX
Найцікавіша частина — два типи полів, написаних з нуля для ACF.
GitHub Repository — каскадний селект. Перший список підтягує репозиторії авторизованого користувача через GitHub API з кешуванням на 15 хвилин. Вибрав репозиторій — другий список завантажує гілки через AJAX, кеш 10 хвилин. Жодного ручного вводу, жодної помилки в назві.
Сайти Хостинг Україна — аналогічна логіка для хостингу. Домен → піддомен. Кожен варіант автоматично зберігає шлях до домашньої директорії сайту на сервері. Все через API adm.tools.
Створюєш деплой — просто вибираєш зі списків. Як конструктор: звідки → куди. Два селекти зліва, два справа. Готово.
Один push — код на сервері
При збереженні запису система генерує унікальний токен — зашифрований ID через AES-256-CBC — і формує URL вебхука. Цей URL автоматично реєструється на GitHub. При видаленні запису webhook видаляється. Усе автоматично.
Коли GitHub надсилає push-подію, починається ланцюжок:
- Розшифровка токена, пошук конфігурації
- Повідомлення в Telegram: «Деплой розпочато»
- Завантаження ZIP-архіву репозиторію з GitHub (авторизація через Personal Access Token)
- Розпакування, очищення цільової директорії, переміщення файлів
- Видалення зайвого:
.md,.gitignore,prepros.config - Повідомлення в Telegram: «Готово» або «Помилка»
Для webhook-деплоїв процес запускається асинхронно — PHP-скрипт у фоні через CLI. GitHub отримує відповідь одразу, не чекає завершення. Для ручних деплоїв через кнопку в адмінці — синхронний режим із результатом прямо в браузер.
Push з телефону, повідомлення в Telegram через хвилину — код уже на сервері. Це той рівень автоматизації, заради якого все і будувалось.
Бонуси, яких не планував
Коли маєш працюючу інфраструктуру з UI та списком усіх сайтів — наступні ідеї з’являються самі.
HTTP Authentication менеджер
Другий Custom Post Type — «Authentication». Вибираєш сайт зі списку, вводиш логін і пароль — система генерує .htpasswd і додає відповідний блок у .htaccess. Видаляєш запис — захист знімається автоматично.
Закрити staging паролем, відкрити для клієнта — два кліки замість SSH-сесії. Є навіть API-ендпоінт для отримання даних авторизації — використовую його у власному Chrome-розширенні, щоб в один клік відкривати сайти, закриті паролем. Але про це розкажу якось згодом — це окрема велика та дуже цікава тема.
Чесно про обмеження
Система не ідеальна. Я це знаю і не роблю вигляд, що це enterprise-рішення.
- Немає rollback — зламав деплой — або пушиш фікс, або відновлюєш із бекапу хостингу. Зберігати попередню версію перед очищенням — у планах, але за півроку роботи потреба не виникала жодного разу
- ZIP замість git clone — кожен деплой завантажує повний архів репозиторію. Для WordPress-тем і плагінів (кілька мегабайт) це некритично, але для великого монорепо було б неефективно
- WordPress як єдина точка — якщо впаде WordPress на цьому сервері, впаде і деплой. За півроку не сталося, але ризик є
- Один хостинг — інтеграція з Хостинг Україна API. Для іншого провайдера потрібно адаптувати
Це інструмент, побудований під конкретні умови конкретного розробника. У цих умовах — тридцять з плюсом проєктів на shared-хостингу — він працює бездоганно.
Підсумок
Більш як тридцять конфігурацій деплою, клієнтські проєкти та пет-проєкти — усе крутиться через один WordPress. Жодного збою за півроку. Жодної зайвої підписки.
Головний висновок: найкраще рішення — не те, яке рекомендують на конференціях. А те, яке побудоване під твої реальні потреби, на інструментах, якими ти віртуозно володієш.
Якщо у вас є бізнес і ви відчуваєте, що ваша інфраструктура тримається на скотчі та ручній роботі — напишіть мені. Я будую речі, які працюють. Під ваші задачі, ваш стек та ваші потреби.