«Когда мне говорят, что 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. Ни одного сбоя за полгода. Ни одной лишней подписки.
Главный вывод: лучшее решение — не то, которое рекомендуют на конференциях. А то, которое построено под твои реальные потребности, на инструментах, которыми ты виртуозно владеешь.
Если у вас есть бизнес и вы чувствуете, что ваша инфраструктура держится на скотче и ручной работе — напишите мне. Я строю вещи, которые работают. Под ваши задачи, ваш стек и ваши потребности.