Миграции в Битриксе - это способ переносить изменения кода, структуры инфоблоков и настроек модулей с тестового сайта на боевой без ручного повторения одних и тех же кликов в админке. На практике беру задачи, где клиент годами правил прод напрямую: добавлял свойства инфоблокам через интерфейс, менял настройки модулей, а потом на новом сервере или после сбоя не мог понять, что где менялось и в каком порядке. Ниже описываю, как выстроить перенос правок так, чтобы прод не ломался при каждом обновлении и было что восстанавливать, если что-то пошло не так.
Что переносить с тестового сайта на прод, кроме файлов
В Битриксе принято думать, что перенос правок это git pull или закачка файлов по FTP. На деле файлы, шаблон компонента, правки в php_interface, это только часть работы. Вторая часть, обычно более болезненная, это структура базы: новые свойства инфоблоков, пользовательские поля, highload-блоки, настройки модулей (список складов, способов оплаты, статусов заказов). Эти вещи не лежат в файлах, их не увидит git diff, и при выкладке кода на прод без соответствующих изменений в базе сайт падает с ошибкой о несуществующем свойстве или поле.
Ещё один слой, про который часто забывают, права доступа к разделам инфоблоков и агенты, которые должны запускаться по расписанию. Если тестовая база создавалась давно, а прод обновлялся точечными правками через админку, структуры расходятся так, что через год-два никто уже не помнит, какая версия правильная.
Контент (товары, статьи, заказы) и структуру (какие поля и блоки вообще существуют) стоит держать раздельно. Контент между тестом и продом переносить обычно не нужно, тестовая база чаще всего урезанная копия боевой без реальных заказов клиентов. А структуру нужно переносить предсказуемо и по порядку, и для этого нужны миграции.
| Критерий | Правки через админку вручную | Миграции (файлы в git) |
|---|---|---|
| Фиксация изменения | нигде, кроме памяти разработчика | в файле миграции и в git-истории |
| Повтор на другом окружении | заново кликами, шаг за шагом | прогон того же файла |
| Откат при ошибке | вручную, легко забыть шаг | через метод отката миграции |
| Риск разойтись между тестом и продом | высокий | низкий |
Бесплатный материал
🎁 Полезный скрипт в подарок
Подпишитесь на Telegram - пришлю готовый скрипт по этой теме.
Без спама. Отписка в 1 клик.
Инструмент миграций для Битрикса: arrilot/bitrix-migrations
В 1С-Битрикс нет миграций из коробки в том смысле, в каком они есть в Laravel или Django. Но есть открытый composer-пакет arrilot/bitrix-migrations, который добавляет ровно этот механизм: миграции хранятся как отдельные PHP-файлы с методами для применения и отката изменений, а какие из них уже выполнены на конкретном сайте, фиксируется в служебной таблице в базе. Подключается пакет через composer require arrilot/bitrix-migrations, дальше в проекте появляется папка с файлами миграций, которые выполняются по порядку номеров.
Смысл в том, что вместо клика «добавить свойство инфоблоку» через админку структура базы описывается кодом, который можно прогнать на любом окружении и получить одинаковый результат. На тесте прогнали, проверили, закоммитили в репозиторий, на проде прогнали те же файлы, и обе базы синхронны.
Как выглядит логика одной миграции
Независимо от конкретной обёртки, в файле миграции обычно определяют метод для применения изменения и метод для отката. Например, миграция, которая создаёт highload-блок под справочник зон доставки, через стандартный D7 API Битрикса выглядит примерно так:
<?php
use Bitrix\Highloadblock\HighloadBlockTable;
class M0001_AddDeliveryZonesHlblock
{
public function up()
{
$result = HighloadBlockTable::add([
'NAME' => 'DeliveryZones',
'TABLE_NAME' => 'b_hlbl_delivery_zones',
]);
if (!$result->isSuccess()) {
throw new \Exception(implode(', ', $result->getErrorMessages()));
}
}
public function down()
{
$hlblock = HighloadBlockTable::getList([
'filter' => ['NAME' => 'DeliveryZones'],
])->fetch();
if ($hlblock) {
HighloadBlockTable::delete($hlblock['ID']);
}
}
}
Такую миграцию можно прогнать на тесте, проверить, что блок создался с нужными полями, и только потом переносить на прод. Если после переноса выяснилось, что поля названы не так, откатывается через метод отката, а не через ручное удаление в админке, где легко забыть один из шагов.
Что удобно оформлять через миграции, а что нет
Через миграции удобно переносить структуру: новые свойства и типы инфоблоков, highload-блоки, пользовательские поля для пользователей и заказов, настройки статусов и способов оплаты, агенты. Плохо ложится в миграции контент и настройки, завязанные на конкретный сервер: пути к папкам с загрузками, лицензионный ключ, SMTP-настройки, ключи интеграций вроде СДЭК или эквайринга, где на тесте и проде обычно используются разные тестовые и боевые значения. Это остаётся в .settings.php или переменных окружения, которые для каждого окружения свои и в репозиторий не попадают.
Процесс деплоя: git, ветки и чек-лист переноса
Рабочая схема, которую использую на проектах на Битриксе: кастомный код (компоненты, шаблоны, обработчики событий, php_interface) живёт в git, ядро Битрикса и модули маркетплейса в репозиторий не кладу, они обновляются отдельно через штатный механизм обновлений системы. Ветка dev для текущей разработки, слияние в ветку под прод только после проверки на тестовом сайте.
Перед каждым переносом на прод прохожу один и тот же чек-лист:
- прогнать миграции на тесте и убедиться, что сайт работает
- сделать бэкап боевой базы и файлов перед переносом
- включить на проде режим технических работ на время деплоя, если правки затрагивают структуру каталога или заказов
- перенести код и сразу следом прогнать те же миграции на проде
- проверить ключевые страницы руками: карточку товара, оформление заказа, форму обратной связи
Порядок важен: код, который ссылается на новое поле инфоблока, нельзя выкладывать раньше, чем это поле появится в базе, иначе первые же посетители увидят ошибку. По этой же причине миграции и код деплою одним пакетом, а не в два подхода с разрывом по времени.
Резервные копии и откат неудачной миграции
Бэкап перед переносом обязателен, и не потому что миграции ненадёжны сами по себе, а потому что правки в структуре боевой базы, которая обслуживает живых пользователей, стоят дороже любой экономии времени. На хостинге обычно достаточно дампа базы через mysqldump и архива директории с сайтом; в панели управления Битрикса есть и штатный модуль резервного копирования, но для больших каталогов дамп средствами MySQL быстрее.
Если после переноса миграция сломала прод, откат идёт в два уровня. Сначала пробую метод отката самой миграции, он убирает только то, что добавил, и обычно быстрее полного восстановления. Если откат неполный, например часть данных в новом поле уже успели заполнить реальные заказы, восстанавливаю сайт из бэкапа целиком и переношу правки заново, уже с исправленной миграцией. Второй сценарий случается редко, но именно поэтому бэкап делаю перед каждым переносом, а не время от времени.
Частые ошибки при переносе правок между тестовым и продакшеном
- Правки напрямую на проде через админку. Один раз добавили свойство инфоблоку на боевом сайте, чтобы быстро проверить гипотезу, и забыли перенести это в миграцию, тест разошёлся с продом.
- Жёстко зашитый числовой ID инфоблока или highload-блока в коде. На тесте и проде ID одной и той же сущности почти никогда не совпадают, потому что порядок создания блоков в базах разный: код с IBLOCK_ID, равным 14 на тесте, сломается там, где на проде тот же инфоблок хранится под ID 21. Правильно ссылаться на инфоблок по символьному коду, а не по числовому ID.
- Миграция без метода отката. Через полгода никто не помнит, что именно делала миграция номер 37, а откатывать нужно прямо сейчас.
- .settings.php с боевыми паролями от базы в репозитории. Настройки окружения должны быть разными для теста и прода и не должны утекать в git вместе с кодом.
- Перенос кода без прогона миграций следом. Код ждёт новое поле, которого в проде ещё нет, сайт отвечает ошибкой 500 на первой же странице, где это поле используется.
Если наводить порядок в таком легаси-проекте самостоятельно некогда, обычно эту часть беру на доработку и поддержку 1С-Битрикс - от 3 000 ₽/час, разово настроить процесс миграций или вести сайт на постоянной основе.
1С-Битрикс регулярно обновляется, поэтому перед внедрением я сверяюсь с актуальной документацией.
Частые вопросы
Нужны ли миграции, если правки на сайте редкие и небольшие?
Если правки раз в несколько месяцев и их можно пересчитать по пальцам, миграции не обязательны, проще вести текстовый журнал изменений и переносить руками по чек-листу. Смысл появляется, когда правок несколько в месяц или в проекте участвует больше одного разработчика, тогда ручной перенос структуры быстро расходится между окружениями.
Как перенести структуру, если много лет правили прод и тест вручную?
Сначала выравниваю базы: сравниваю структуру инфоблоков, полей и highload-блоков на тесте и проде, привожу к одному состоянию вручную один раз. После этого подключаю миграции, и с этой точки все новые изменения идут только через них, без возврата к правкам напрямую через админку.
Можно ли хранить шаблоны и компоненты Битрикса в git вместе с миграциями?
Да, кастомные шаблоны, компоненты и обработчики событий обычно лежат в том же репозитории, что и папка с файлами миграций, это один и тот же деплой. Ядро системы и модули из маркетплейса в репозиторий не кладу, они обновляются отдельно через штатный механизм обновлений Битрикса.
Что делать, если после переноса сайт на проде отвечает ошибкой 500?
Первым делом смотрю лог PHP на предмет undefined property или отсутствующей таблицы, это почти всегда значит, что код уже обновился, а миграция ещё не прогналась на проде. Прогоняю миграции и проверяю страницу заново. Если ошибка не пропадает, откатываю код и миграцию до последней рабочей версии из бэкапа и разбираюсь на тесте.