-10%Переходите к нам от другого подрядчика — дадим скидку на первый этап работ

CI/CD и деплой для 1С-Битрикс: Git, окружения и миграции

CI/CD и деплой для 1С-Битрикс: Git, окружения dev stage prod, миграции структуры и деплой без простоя

Типичная картина на магазине, который развивался «как получится»: разработчик открывает FileZilla, подключается к боевому серверу, правит template.php прямо в каталоге сайта, обновляет страницу — и либо всё хорошо, либо покупатели видят белый экран с фатальной ошибкой PHP. Истории изменений нет, отката нет, ревью нет. Любая правка — это ставка на выручку в прямом эфире. Рано или поздно такой подход стоит либо потерянного заказа, либо нескольких часов ночного восстановления «как было». CI/CD и Git существуют ровно для того, чтобы этой лотереи не было: код версионируется, проходит проверки на копии боевого окружения и выкатывается на прод по единому, повторяемому и обратимому сценарию.

Эта статья — практическая карта того, как выстроить деплой для 1С-Битрикс по-взрослому. Разберём, почему правки на проде по FTP — это плохо, как применять Git для 1С-Битрикс (что версионировать: /local, шаблоны, компоненты, свой код; что игнорировать: ядро /bitrix, загрузки, кэш, настройки базы), как устроены окружения dev/stage/prod и как их синхронизировать, в чём главная особенность платформы — разделение данных и кода (контент живёт в базе, а не в репозитории), что такое миграции битрикс для структуры (свойства инфоблоков, пользовательские поля, опции модулей), как собрать пайплайн (сборка → тесты → деплой → откат), как сделать деплой без простоя с атомарным переключением и прогревом кэша, как хранить секреты по окружениям через .settings.php и почему обновление ядра идёт отдельным потоком. Материал — выжимка из практики наших highload-проектов на 1С-Битрикс, где цена простоя и ошибки релиза особенно высока.

Коротко

  • Правки на проде по FTP лишают проект истории, ревью, тестов и отката — на боевом магазине это прямой риск для выручки.
  • Git для 1С-Битрикс версионирует код: /local, шаблоны, компоненты, свой код и миграции; игнорирует ядро /bitrix, /upload, кэш и настройки базы с паролями.
  • Окружения dev/stage/prod дают ступени проверки: пишем на dev, принимаем на stage (копия прода), выкатываем на prod только проверенное.
  • Данные и код разделены: контент из базы и /upload синхронизируют с прода назад, а структуру (свойства, опции) двигают вперёд через миграции битрикс.
  • Пайплайн CI/CD — commit → build → test → deploy; деплой без простоя делают атомарным переключением симлинка с прогревом кэша, откат — обратным переключением.

Зачем магазину на Битриксе CI/CD и Git

1С-Битрикс — платформа, на которой держатся тысячи боевых магазинов со сложной логикой: каталоги на десятки тысяч товаров, обмен с 1С, оплаты, интеграции. Цена ошибки на таком проекте измеряется не «неудобством», а потерянными заказами и репутацией. При этом исторически многие проекты на Битриксе развивались без инженерной дисциплины: код правили прямо на сервере, никакого репозитория, никаких окружений. Это работает ровно до первого серьёзного инцидента.

CI/CD и Git решают три задачи, которые чувствуются на каждом проекте с первого же дня:

Важно сразу зафиксировать: CI/CD на Битриксе — это не «поставить модный инструмент», а изменить процесс. Инструменты (Git, раннеры, скрипты деплоя) вторичны. Первично разделение окружений, дисциплина «код только через репозиторий» и понимание, что на этой платформе живёт в Git, а что нет. С этого понимания и начнём.

Почему «правки на проде по FTP» — это плохо

«Быстро поправить прямо на боевом» кажется экономией времени, но на деле это отказ сразу от нескольких страховок. Разберём по пунктам, что именно теряется, — потому что каждый пункт превращается в реальный инцидент.

Отдельная опасность — потеря правок при обновлении. Если кто-то поправил прямо в компоненте ядра или в тиражном шаблоне в каталоге /bitrix, ближайшее обновление модуля просто перезапишет эту правку. Именно поэтому в Битриксе всё кастомное выносят в /local — но об этом ниже.

Ключевая мысль: вопрос не в том, «сломается ли когда-нибудь правка на проде по FTP» — сломается обязательно. Вопрос в том, застанет ли вас поломка со страховкой (Git, stage, откат) или без неё, ночью, с открытым FileZilla и без понимания, как было раньше. CI/CD — это и есть страховка.

Git для 1С-Битрикс: что это меняет

Git — это система контроля версий: она хранит полную историю изменений кода, позволяет вести параллельные ветки, сливать их, откатываться к любому состоянию и работать команде над одним проектом без затирания правок друг друга. Для Битрикса Git — фундамент всего CI/CD: именно репозиторий становится единственным источником правды о коде проекта.

Что конкретно меняется, когда проект переезжает под Git:

Но у Битрикса есть своя специфика, которая отличает его от «обычного» PHP-проекта. Здесь код перемешан с ядром платформы в одной файловой структуре, а значительная часть системы вообще не является файлами — она в базе данных. Поэтому нельзя просто сделать git init в корне сайта и закоммитить всё подряд: в репозиторий попадёт гигантское ядро, пользовательские загрузки и пароли от базы. Первый и главный навык работы с Git на Битриксе — чётко понимать, что версионировать, а что нет. Этому посвящён следующий раздел.

Что версионировать, а что игнорировать

Разделение файлов Битрикса на «код проекта» и «всё остальное» — центральное решение при настройке репозитория. Ошибка здесь дорого обходится: закоммитите лишнее — получите конфликты с обновлениями ядра и утечку паролей; забудете нужное — потеряете часть проекта. Держите перед глазами простое правило: в Git едет то, что создаёт разработчик и что одинаково для всех окружений.

ЧтоВ Git?Почему
/local целикомДаСвои компоненты, шаблоны, модули, обработчики /local/php_interface — это ваш код
Шаблоны сайтаДаВёрстка, стили, скрипты шаблона — создаются руками, одинаковы на всех средах
Кастомные компонентыДаВаши component.php, шаблоны компонентов, result_modifier
Миграции структурыДаВерсионированные сценарии изменения свойств, полей, опций
Конфиги окружений (без секретов)ДаШаблоны настроек, composer.json, скрипты деплоя, CI-конфиги
Ядро /bitrixНетОбновляется механизмом SiteUpdate — не должно ехать через деплой
Загрузки /uploadНетПользовательский контент; место в резервных копиях, не в Git
Кэш /bitrix/cache, managed_cacheНетГенерируется на лету, специфичен для среды
.settings.php, dbconn.phpНетСодержат пароли и параметры конкретного окружения

Почему /local — герой этой истории. Битрикс поддерживает два каталога для кастомизации: старый /bitrix/templates, /bitrix/components и параллельный /local с той же структурой. Всё, что лежит в /local, платформа подхватывает автоматически, но обновления ядра его не трогают. Поэтому современный подход — держать весь свой код в /local: тогда репозиторий проекта — это, по сути, каталог /local плюс несколько файлов конфигурации, а не вся файловая структура сайта. Это радикально упрощает и Git, и деплой.

Почему ядро /bitrix и загрузки /upload вне Git. Ядро — это не ваш код, а тело платформы, которое живёт своей жизнью: его правит обновлятор Битрикса. Если положить /bitrix в репозиторий, вы получите постоянные конфликты между деплоем и SiteUpdate. Каталог /upload — это пользовательский контент (картинки товаров, документы, аватары): он огромный, меняется на проде каждую минуту и не имеет никакого отношения к коду. Ему место в системе резервного копирования, о которой мы подробно пишем в статье про хостинг и инфраструктуру BitrixVM.

Файлы Битрикса: что в Git, а что игнорируем Версионируем (код проекта) /local — компоненты, шаблоны, модули, php_interface шаблоны сайта, стили, скрипты кастомные компоненты миграции структуры composer.json, CI-конфиги шаблоны настроек (без паролей) одинаково на всех окружениях Игнорируем (.gitignore) /bitrix — ядро платформы (обновляется SiteUpdate) /upload — загрузки, контент /bitrix/cache, managed_cache .settings.php с паролями dbconn.php, ключи, токены логи, временные файлы данные, кэш и секреты — отдельно
Схема: в Git едет код проекта, одинаковый для всех окружений (в основном каталог /local и конфиги), а ядро, загрузки, кэш и секреты остаются за пределами репозитория — у них другой жизненный цикл.

.gitignore для проекта на Битриксе

Практическое воплощение предыдущего раздела — файл .gitignore в корне репозитория. Он описывает, что Git должен игнорировать. Есть два подхода к структуре репозитория: держать в Git весь корень сайта, но игнорировать лишнее, либо (что чище) сделать репозиторием только каталог /local. Ниже — вариант .gitignore для случая, когда репозиторий охватывает корень сайта:

# Ядро платформы — обновляется механизмом SiteUpdate, не через деплой
/bitrix/*
# Но свои правки в настройках админки можно версионировать выборочно
!/bitrix/.gitkeep

# Пользовательский контент и загрузки — в резервные копии, не в Git
/upload/

# Кэш всех видов — генерируется на лету
/bitrix/cache/
/bitrix/managed_cache/
/bitrix/stack_cache/
/bitrix/html_pages/

# Секреты и настройки конкретного окружения — НИКОГДА в Git
/bitrix/.settings.php
/bitrix/php_interface/dbconn.php
/bitrix/.settings_extra.php
.env

# Логи, временные и системные файлы
*.log
/bitrix/tmp/
.DS_Store
Thumbs.db

# Зависимости, которые ставятся при сборке
/local/vendor/
/node_modules/

Несколько принципиальных замечаний. Строку с .settings.php и dbconn.php нельзя ослаблять ни при каких условиях — это файлы с паролем от базы данных и ключами. Если они хоть раз попадут в историю Git, считайте пароли скомпрометированными: их придётся менять, а историю чистить. Каталог /upload исключён целиком, потому что версионировать пользовательский контент бессмысленно и вредно — он раздувает репозиторий и постоянно расходится между окружениями.

Проверьте до первого коммита: выполните git status и убедитесь, что в списке на добавление нет /upload, ядра /bitrix и файлов с настройками базы. Если .settings.php уже попал в индекс — уберите его через git rm --cached до коммита. Утечку секретов проще предотвратить, чем потом вычищать из всей истории репозитория.

Окружения dev, stage, prod

Второй столп CI/CD после Git — разделение окружений. Окружение (environment) — это отдельная площадка, где работает копия проекта со своей базой и своими данными, но с одним и тем же кодом. Классическая схема — три окружения, каждое со своей ролью.

ОкружениеРольДанныеКто работает
dev (development)Разработка и отладка кодаТестовые или обезличенная копияРазработчики
stage (staging, предпрод)Приёмка релиз-кандидата, регресс, проверка миграцийСвежая обезличенная копия продаQA, заказчик, тимлид
prod (production)Боевой сайт для покупателейРеальные «живые» данныеТолько автоматический деплой

Логика движения кода простая и односторонняя: изменение рождается на dev, проходит ревью и вливается в основную ветку, автоматически едет на stage, где его принимают и проверяют миграции на копии боевой базы, и только после успешной приёмки выкатывается на prod. Ничего не попадает на прод, минуя stage, — это железное правило.

Критически важное требование к stage — максимальная похожесть на prod. Одинаковая версия PHP, те же настройки веб-сервера и модулей, тот же стек BitrixVM, актуальная по структуре база. Если stage отличается от прода по версии PHP или конфигурации, проверка на нём теряет смысл: релиз может пройти на stage и упасть на проде. Именно на stage прогоняют приёмочное тестирование и QA магазина перед каждым выкатом.

Окружения: код едет вперёд, данные — назад dev разработка кода отладка, эксперименты тестовые данные stage приёмка, регресс проверка миграций копия прода prod боевой сайт покупатели живые данные деплой релиз копия базы и /upload с прода (обезличенная) → на stage и dev
Схема: код движется вперёд dev → stage → prod через ревью и деплой, а данные (обезличенная копия базы и загрузок) копируются в обратную сторону — с прода на stage и dev, чтобы разработка шла на реалистичных данных.

Синхронизация окружений

Из схемы выше видно главное: код и данные синхронизируются в противоположных направлениях. Это, пожалуй, самая частая точка непонимания у команд, которые впервые строят CI/CD на Битриксе, поэтому разберём подробно.

Код едет вперёд. Новые компоненты, шаблоны, обработчики, миграции создаются на dev и через Git и деплой продвигаются к проду. Направление всегда одно: dev → stage → prod. Обратно код с прода не забирают — на проде его никто не пишет.

Данные едут назад. Реальные товары, заказы, страницы, картинки живут на проде и там же меняются каждую минуту. Чтобы разработка и тесты были реалистичными, свежую копию боевой базы и каталога /upload периодически переносят на stage и dev. Направление обратное: prod → stage → dev.

При переносе данных назад есть обязательный шаг — обезличивание персональных данных. Копия боевой базы содержит телефоны, адреса и e-mail покупателей, и на dev/stage их держать в открытом виде нельзя ни по закону, ни по здравому смыслу. Поэтому после копирования базы прогоняют скрипт анонимизации: заменяют персональные данные на фиктивные, обнуляют реальные платёжные реквизиты, подменяют e-mail сотрудников на тестовые, чтобы случайные письма из dev не улетали клиентам.

Отдельно про почту и обмен: на stage и dev обязательно отключают или подменяют «боевые» интеграции — реальную отправку писем, боевой обмен с 1С, боевые платёжные шлюзы. Иначе тестовый заказ на stage уйдёт в 1С как настоящий, а письмо о смене статуса прилетит живому покупателю. Разные ключи и адреса интеграций для разных окружений — часть управления секретами, к которому мы вернёмся ниже.

Данные против кода: контент в БД, а не в Git

Теперь — о самой болезненной особенности Битрикса в контексте деплоя. В «классическом» PHP-приложении почти вся логика — это файлы, и Git ими полностью управляет. В Битриксе значительная часть системы живёт не в файлах, а в базе данных: структура инфоблоков и их свойства, пользовательские поля, настройки модулей, сами товары и заказы, тексты страниц, настройки форм, права доступа. Git этого не видит и видеть не должен.

Из этого следует ключевое разделение, которое нужно держать в голове всё время:

Почему нельзя просто «выгрузить базу с dev и залить на prod». Потому что база прода — живая. Пока разработчик неделю пилил фичу на dev, на проде оформили сотни заказов, поменяли остатки, зарегистрировались новые пользователи. Заливка dev-базы на prod уничтожит всё это. Поэтому базу целиком в направлении «вперёд» не двигают никогда — вперёд едут только точечные, описанные кодом изменения структуры.

Отсюда и вырастает необходимость миграций. Если разработчик добавил на dev новое свойство инфоблока через админку, это изменение застряло в его локальной базе. Код, который на это свойство рассчитывает, поедет через Git на прод — а свойства там не будет, и код упадёт. Миграция решает эту рассинхронизацию: она описывает изменение структуры как код и применяет его на каждом окружении отдельно.

Миграции структуры: свойства, поля, опции

Миграция — это версионированный сценарий изменения структуры данных, который применяется одинаково на всех окружениях и хранит отметку, что он уже проведён. Идея пришла из мира фреймворков (Laravel, Symfony), но для Битрикса особенно важна из-за того, что «структура» здесь особенно богата: свойства инфоблоков, пользовательские поля, highload-блоки, опции модулей, почтовые события, типы плательщиков.

Что обычно оформляют миграциями на Битриксе:

Как это работает механически. Каждая миграция — это класс или файл с методами «применить» (up) и «откатить» (down). Система хранит в базе список уже применённых миграций. При деплое пайплайн вызывает команду «провести непроведённые миграции», она находит новые файлы, применяет их по порядку и записывает отметки. На следующем окружении та же команда прогонит те же миграции — структура придёт к идентичному состоянию.

В экосистеме Битрикса для этого есть готовые модули миграций (например, известные решения от сообщества), которые умеют не только выполнять произвольный код в up/down, но и «снимать» изменения структуры из админки в виде готовой миграции — это удобно, когда свойство проще создать мышкой, а потом зафиксировать как код. Упрощённо файл миграции выглядит так:

<?php
// Миграция: добавить строковое свойство "Бренд" к инфоблоку товаров
class AddBrandProperty20240326 extends Migration
{
    public function up()
    {
        $iblockId = $this->getIblockIdByCode('catalog');
        $this->addIblockProperty($iblockId, [
            'NAME'      => 'Бренд',
            'CODE'      => 'BRAND',
            'PROPERTY_TYPE' => 'S',      // строка
            'IS_REQUIRED'   => 'N',
            'SORT'      => 500,
        ]);
    }

    public function down()
    {
        // Обратное действие — удалить свойство при откате миграции
        $iblockId = $this->getIblockIdByCode('catalog');
        $this->deleteIblockPropertyByCode($iblockId, 'BRAND');
    }
}

Дисциплина здесь такая же строгая, как с Git: любое изменение структуры оформляется миграцией, а не «руками на проде». Если контент-менеджеру нужно свойство «на посмотреть» — это одно, но всё, на что опирается код, обязано существовать как миграция. Иначе рано или поздно stage или prod получат код без структуры под него, и релиз упадёт.

Тонкость с данными в миграциях: миграции меняют структуру, а не наполняют её контентом. Не пытайтесь миграцией залить тысячу товаров — это данные, им место в базе, которую вы синхронизируете дампами. Миграцией уместно создать справочник статусов или единичные служебные записи, без которых код не работает, но массовый контент через миграции не гоняют.

.settings.php и секреты по окружениям

Раз код в Git одинаков для всех окружений, а параметры подключения к базе, ключи интеграций и адреса сервисов у dev, stage и prod разные, нужен механизм, который разводит секреты по окружениям. В Битриксе основные точки — файл /bitrix/.settings.php (современное хранилище настроек ядра: подключение к базе, кэш, соединения) и старый dbconn.php. Оба содержат пароли и оба исключены из Git.

Правильная схема работы с настройками окружений:

Битрикс позволяет расширять настройки через .settings_extra.php — этот файл тоже вне Git и дополняет основной. Удобный приём — определять окружение через переменную окружения веб-сервера и подмешивать её в код:

<?php
// В /local/php_interface/init.php — определяем текущее окружение
$environment = getenv('APP_ENV') ?: 'prod';   // dev | stage | prod
define('APP_ENV', $environment);

// Дальше по окружению включаем нужное поведение
if (APP_ENV !== 'prod') {
    // На не-боевых окружениях — режим отладки и подмена почты
    define('BX_DEBUG', true);
}

// Ключи и адреса интеграций берём из окружения, а не из кода
$paymentApiKey = getenv('PAYMENT_API_KEY');   // разный для dev/stage/prod
$oneCUrl       = getenv('ONE_C_EXCHANGE_URL');

Главное правило безопасности повторим ещё раз, потому что оно стоит дороже всего: секретам не место в репозитории. Пароль от боевой базы, попавший в историю Git, — это инцидент безопасности, даже если репозиторий приватный. Разграничение доступа и защита секретов — часть более широкой темы безопасности, которую мы затрагиваем в материале про безопасное обновление 1С-Битрикс.

Ветки, code review и модель работы

Git даёт ветки — но пользоваться ими нужно по договорённости, иначе в репозитории быстро наступит хаос. Команде нужна ветвочная модель (branching strategy) — согласованные правила, как заводить ветки, как их называть и как вливать.

Для проектов на Битриксе обычно достаточно облегчённой модели с несколькими типами веток:

Механика такая. Разработчик заводит ветку под задачу, пишет код, коммитит осмысленными порциями с внятными сообщениями. Когда задача готова — открывает запрос на слияние (Pull Request / Merge Request). Здесь начинается code review: другой разработчик читает изменения, задаёт вопросы, просит поправить. Одновременно CI-система на этот PR прогоняет автоматические проверки — линтеры, тесты. Ветка вливается в основную только когда пройдено и ревью, и автопроверки.

Зачем это на Битриксе, где «и так всё работало». Ревью ловит целый класс ошибок до прода: обращение к несуществующему свойству, отсутствующую миграцию под новый код, забытую проверку прав, неоптимальную выборку, которая положит каталог под нагрузкой. Один потраченный на ревью час экономит несколько часов ночного разбора инцидента. А привязка PR к задаче даёт прослеживаемость: по любой строке кода видно, зачем она появилась.

Мостик к миграциям: на ревью полезно ввести обязательный вопрос — «есть ли под этот код миграция структуры?». Если PR добавляет обращение к новому свойству инфоблока или пользовательскому полю, но в изменениях нет соответствующей миграции, значит на stage и prod код упадёт. Такой чек-пункт в ревью ловит самую частую причину «работало на dev, упало на проде».

Пайплайн CI/CD: из чего он состоит

Когда есть Git, окружения и миграции, поверх них выстраивают пайплайн — автоматизированную последовательность шагов, которую проходит каждое изменение от коммита до боевого сайта. Пайплайн запускается автоматически по событию (пуш в ветку, слияние PR) и выполняет шаги по порядку; если шаг падает — конвейер останавливается и дальше код не едет.

Канонический пайплайн для Битрикса состоит из последовательности этапов:

  1. Commit (коммит и триггер). Разработчик пушит ветку или вливает PR в основную. CI-система ловит событие и запускает пайплайн — с этого момента всё автоматически.
  2. Build (сборка). Ставятся зависимости (composer install, сборка фронтенда), собираются ассеты, готовится артефакт — набор файлов, который поедет на сервер. Ничего, что можно собрать заранее, не делается на боевом сервере.
  3. Test (проверки и тесты). Прогоняются линтеры, проверка синтаксиса PHP (php -l), статический анализ и автотесты. Падение любой проверки останавливает пайплайн — плохой код на прод не поедет.
  4. Deploy на stage. Артефакт выкладывается на предпрод, прогоняются миграции, окружение прогревается. Здесь идёт приёмка и регресс на копии боевых данных.
  5. Deploy на prod. После приёмки — выкладка на боевой сайт атомарным переключением, прогон миграций, прогрев кэша. Обычно этот шаг запускают вручную (по кнопке), чтобы контролировать момент релиза.
  6. Rollback (откат) при сбое. Если после релиза что-то пошло не так, одной командой возвращаемся на предыдущий релиз. Возможность отката — обязательная часть пайплайна, а не «на всякий случай».

Обратите внимание: между «test» и «deploy на prod» стоит человеческий контроль — приёмка на stage и, как правило, ручной запуск боевого релиза. Полностью автоматический деплой на прод (continuous deployment) на магазинах применяют осторожно: цена ошибки высока, и большинство команд оставляет финальную кнопку за человеком. Это нормальный и разумный компромисс.

Пайплайн: commit → build → test → deploy Commit пуш / PR Build composer, ассеты Test php -l, линтеры Deploy stage → prod + миграции Live сайт Rollback: сбой на любом шаге останавливает конвейер; после релиза — обратное переключение на предыдущий релиз
Схема: каждое изменение проходит конвейер commit → build → test → deploy; падение любого шага останавливает выкат, а после релиза остаётся возможность быстрого отката на предыдущий релиз.

Сборка проекта (build)

Этап сборки часто недооценивают на Битриксе — «зачем что-то собирать, это же просто PHP-файлы». Но как только на проекте появляются зависимости через Composer, сборка фронтенда (Webpack, Vite, сборка стилей) или генерируемые ассеты, шаг build становится необходимым. Его смысл — подготовить готовый к работе артефакт до того, как он попадёт на сервер.

Что обычно делают на этапе сборки:

Главный принцип: ничего тяжёлого не делается на боевом сервере. Устанавливать Composer-зависимости или собирать фронтенд прямо на проде во время релиза — плохо: это долго, нагружает сервер и создаёт окно, когда файлы уже частично обновлены. Всё это делают на раннере (машине сборки) заранее, а на сервер отправляют уже готовый, проверенный артефакт.

# Пример шага сборки (упрощённо)
# 1. Ставим PHP-зависимости для боевого окружения
composer install --no-dev --optimize-autoloader --no-interaction

# 2. Собираем фронтенд шаблона
npm ci
npm run build

# 3. Готовим артефакт — только то, что едет на сервер
tar -czf build.tar.gz local/ composer.json composer.lock

Тесты и проверки в пайплайне

Этап проверок — то, что превращает пайплайн из «просто автозаливки» в защитный барьер. Его задача — не пустить заведомо сломанный код дальше по конвейеру. Проверки идут от самых дешёвых и быстрых к более дорогим, и первая же неудача останавливает пайплайн.

Типичный набор проверок для проекта на Битриксе:

Специфика Битрикса в том, что полноценные автотесты писать сложнее, чем в чистом фреймворке: ядро завязано на глобальное состояние и базу. Поэтому на многих проектах на Битриксе тестовый этап начинается с малого — синтаксис, линтеры, статический анализ и приёмочное тестирование на stage вручную — и постепенно обрастает автотестами для критичных участков. Как выстроить тестирование магазина системно, от чек-листов до автоматизации, подробно разобрано в статье про тестирование и QA интернет-магазина на 1С-Битрикс.

# Пример этапа проверок в пайплайне
# Синтаксис всех изменённых PHP-файлов
git diff --name-only --diff-filter=ACM origin/main | grep '\.php$' \
  | xargs -r -n1 php -l

# Статический анализ и стандарт кода
vendor/bin/phpstan analyse local/ --level=5
vendor/bin/phpcs --standard=PSR12 local/

# Автотесты
vendor/bin/phpunit --testsuite=unit

Деплой: как код попадает на сервер

Деплой — этап доставки готового артефакта на сервер и его активации. Способов доставки несколько, и они принципиально различаются по надёжности и удобству отката.

Для боевого магазина на Битриксе третий вариант — стандарт де-факто, потому что только он даёт атомарность и мгновенный откат. Структура каталогов при таком подходе выглядит так:

/var/www/shop/
├── releases/                  # все выложенные релизы
│   ├── 2024-03-25-1410/
│   ├── 2024-03-26-0930/
│   └── 2024-03-26-1530/       # текущий
├── shared/                    # общее для всех релизов
│   ├── upload/                # загрузки — не копируются с релизом
│   ├── bitrix/                # ядро — общее, обновляется отдельно
│   └── .settings.php          # секреты окружения
└── current -> releases/2024-03-26-1530/   # симлинк на активный релиз

Здесь current — символическая ссылка, на которую настроен веб-сервер. Общие для всех релизов вещи (загрузки, ядро, настройки) вынесены в shared и подключаются к каждому релизу симлинками — поэтому они не дублируются и переживают переключение. Сам новый релиз готовится в стороне, никак не влияя на работающий сайт, — и только финальное переключение current делает его активным.

Деплой без простоя и прогрев кэша

Главная ценность релизов через симлинк — деплой без простоя (zero-downtime). Разберём по шагам, как одно изменение выкатывается на боевой магазин так, чтобы ни один посетитель не увидел ни ошибки, ни «сайт на техобслуживании».

  1. Выкладка нового релиза в сторону. Артефакт распаковывается в новый каталог releases/2024-03-26-1530. Веб-сервер в это время продолжает отдавать старый релиз через current — посетители ничего не замечают.
  2. Подключение общих ресурсов. К новому релизу симлинками подключаются shared/upload, shared/bitrix, реальный .settings.php. Релиз становится полноценным, но пока неактивным.
  3. Прогон миграций. Применяются непроведённые миграции структуры. Важно: миграции пишут совместимыми с обеими версиями кода (об этом ниже), чтобы старый релиз не сломался, пока переключение ещё не произошло.
  4. Атомарное переключение. Симлинк current одной операцией переводится на новый каталог. Это происходит мгновенно; запросы, начатые на старом релизе, завершаются на нём, новые идут на новый.
  5. Прогрев кэша. Скрипт делает запросы к ключевым страницам (главная, каталог, карточка товара), чтобы сгенерировать кэш заранее. Первый живой посетитель попадает уже на «тёплый» сайт, а не на медленную холодную генерацию.

Отдельно про кэш Битрикса. После переключения релиза часть кэша может стать неактуальной (изменились шаблоны компонентов). Поэтому в сценарий деплоя включают сброс нужных видов кэша и последующий прогрев. Делать это надо аккуратно: полный сброс всего кэша на нагруженном магазине в час пик создаёт всплеск нагрузки, пока кэш регенерируется. Как устроены слои кэша и как их правильно инвалидировать, мы разбираем в отдельном материале по кэшированию Битрикса; здесь важно правило — сбрасывать точечно и сразу прогревать.

Деплой без простоя: переключение симлинка Релиз N-1 2024-03-26-0930 Релиз N (новый) 2024-03-26-1530 current симлинк Веб-сервер посетители переключить откат ← Переключение атомарно → простоя нет → прогрев кэша откат = вернуть симлинк current на релиз N-1 (мгновенно)
Схема: новый релиз готовится в отдельном каталоге, пока сайт работает на старом; симлинк current атомарно переключается на новый релиз, кэш прогревается — простоя нет. Откат — обратное переключение симлинка на предыдущий релиз.

Откат релиза

Возможность быстрого отката — не «приятная опция», а обязательная часть зрелого деплоя. Идея проста: если после релиза обнаружилась проблема, вы должны вернуть рабочее состояние быстрее, чем будете разбираться в причине. Сначала стабилизировать сайт, потом чинить — а не наоборот, под давлением идущих ошибок.

При релизах через симлинк откат кода тривиален: старые релизы никуда не делись, они лежат в releases/. Откат — это переключение current обратно на предыдущий каталог, ровно та же атомарная операция, что и выкат, только в обратную сторону:

# Откат: вернуть симлинк current на предыдущий релиз
ln -sfn /var/www/shop/releases/2024-03-26-0930 /var/www/shop/current

# Сбросить и прогреть кэш под откатанный релиз
php /var/www/shop/current/local/tools/cache_clear.php
curl -s -o /dev/null https://shop.example.ru/    # прогрев главной

Но у Битрикса откат сложнее, чем «переключить файлы обратно», из-за миграций и данных. Код откатывается мгновенно, а вот изменения структуры базы так просто не отматываются. Здесь два принципа спасают ситуацию:

Это подводит к важному правилу проектирования миграций: предпочитайте аддитивные, обратно совместимые изменения. Добавить новое свойство безопаснее, чем переименовать существующее; выкатывать удаление старого — отдельным, поздним релизом, когда уже точно ничего на него не опирается. Такой подход делает откат кода безопасным даже без отката базы — что на практике и требуется в 90% инцидентов.

Резервная копия перед боевым релизом — обязательна. Даже с обратимыми миграциями перед выкатом на прод делают резервную копию базы. Симлинк вернёт код, метод down отменит структуру, но если миграция успела необратимо тронуть данные, единственная страховка — свежий бэкап. Автоматический снимок базы прямо перед прод-релизом — дешёвая страховка, которая однажды спасёт проект.

Обновление ядра отдельно от деплоя

Отдельная и часто недооценённая тема — обновления ядра Битрикса. Ключевой тезис: обновление ядра — это не деплой вашего кода, это независимый поток изменений, у которого свои правила. Смешивать их нельзя.

Причина в том, что каталог /bitrix принадлежит платформе, а не вам, и меняется собственным механизмом — технологией SiteUpdate. Обновлятор скачивает новые версии модулей, применяет патчи к файлам ядра и, что важно, вносит изменения в структуру базы данных под новую версию. Если положить /bitrix в Git и выкатывать релизом, вы получите два конфликтующих источника правды: деплой перезапишет то, что обновил SiteUpdate, версия файлов разъедется с версией базы, и начнутся трудноуловимые ошибки.

Поэтому потоки разводят:

Порядок безопасного обновления ядра такой же дисциплинированный, как и деплой: сделать бэкап, обновить на stage, прогнать регресс (особенно то, что касается изменённых модулей), убедиться, что ваш код совместим с новой версией, и лишь затем повторить на проде в спокойное время с бэкапом под рукой. Эта тема заслуживает отдельного разговора — как обновлять ядро и модули, не сломав боевой магазин, мы подробно разбираем в статье про безопасное обновление 1С-Битрикс.

Практический вывод для CI/CD: ваш пайплайн должен уметь работать с окружением, где ядро обновляется независимо. Отсюда и вынос /bitrix в shared при релизах через симлинк — ядро общее для всех релизов вашего кода и живёт своей жизнью, не привязанной к вашим выкатам.

Инструменты CI/CD под Битрикс

Процесс важнее инструментов, но без инструментов процесс не автоматизировать. Коротко о том, из чего обычно собирают конвейер для проекта на Битриксе — без привязки к конкретному вендору, потому что принципы одинаковы.

СлойЧто делаетТипичные варианты
Хостинг репозиторияХранит код, ветки, PR, ревьюGitLab, GitHub, Gitea, Bitbucket
CI-раннерЗапускает пайплайн: сборку, тестыGitLab CI, GitHub Actions, Jenkins
Инструмент деплояДоставка и атомарное переключениеDeployer, самописные скрипты, Ansible
Модуль миграцийВерсионирование структуры БитриксаРешения сообщества для миграций
Хранилище секретовКлючи и пароли по окружениямСекреты CI, переменные окружения, Vault

Как это связывается в единое целое. Код лежит в GitLab/GitHub. При пуше в ветку CI-раннер (GitLab CI / GitHub Actions) поднимает окружение, ставит зависимости, гоняет проверки. При слиянии в основную ветку раннер собирает артефакт и вызывает инструмент деплоя (например, Deployer), который выкладывает релиз через симлинк на stage, прогоняет миграции и прогревает кэш. Прод-релиз запускается по кнопке. Секреты берутся из защищённого хранилища CI, а не из кода. Ниже — как выглядит фрагмент описания пайплайна для одной из систем:

# .gitlab-ci.yml — упрощённый пример конвейера
stages: [build, test, deploy]

build:
  stage: build
  script:
    - composer install --no-dev --optimize-autoloader
    - npm ci && npm run build
  artifacts:
    paths: [local/]

test:
  stage: test
  script:
    - find local -name '*.php' -print0 | xargs -0 -n1 php -l
    - vendor/bin/phpstan analyse local/ --level=5

deploy_stage:
  stage: deploy
  script:
    - vendor/bin/dep deploy stage      # выкладка релиза + миграции
  environment: stage

deploy_prod:
  stage: deploy
  script:
    - vendor/bin/dep deploy prod
  environment: prod
  when: manual                          # прод — только по кнопке

Не гонитесь за «идеальным стеком» сразу. Рабочая стратегия — начать с малого: репозиторий с правильным .gitignore, два-три окружения, простой скрипт деплоя, проверка php -l. Это уже радикально надёжнее правок по FTP. Дальше конвейер обрастает миграциями, автотестами и атомарным переключением по мере роста проекта. Внедрение и поддержку такой инфраструктуры мы берём на себя в рамках поддержки 1С-Битрикс.

Частые ошибки

CI/CD на Битриксе спотыкается о повторяющийся набор граблей. Зная их заранее, вы обойдёте большинство болезненных инцидентов.

Чек-лист внедрения CI/CD

Короткий список, по которому удобно свериться при постановке процесса деплоя на проекте 1С-Битрикс:

Вывод

CI/CD и деплой для 1С-Битрикс — это не про модные инструменты, а про инженерную дисциплину, которая убирает лотерею из работы с боевым магазином. Фундамент — Git с чётким разделением «код в репозитории, ядро/данные/секреты вне его»: в версионирование едет /local, шаблоны, компоненты, свой код и миграции, а ядро /bitrix, загрузки /upload, кэш и .settings.php остаются за его пределами. Поверх Git выстраиваются окружения dev/stage/prod, где код движется вперёд, а обезличенные данные — назад, и пайплайн build → test → deploy, который не пускает сломанный код к покупателям.

Главная особенность платформы, которую нельзя игнорировать, — разделение данных и кода: контент живёт в базе и синхронизируется дампами, а структуру (свойства инфоблоков, поля, опции) продвигают вперёд миграциями с обратимыми down. Деплой без простоя достигается атомарным переключением симлинка с прогревом кэша, откат — обратным переключением, а обновление ядра идёт отдельным контролируемым потоком, не смешиваясь с выкатом кода. Начать можно с малого — репозиторий, правильный .gitignore, stage и простой скрипт деплоя — и это уже несоизмеримо надёжнее правок по FTP. Если нужно поставить такой процесс под ваш проект, мы делаем это в рамках highload-проектов на 1С-Битрикс и поддержки. Смежные материалы по теме — тестирование и QA магазина, хостинг и инфраструктура BitrixVM, безопасное обновление Битрикса и вся рубрика «Разработка и архитектура».

Частые вопросы

Что такое CI/CD для 1С-Битрикс простыми словами?

CI/CD — это две связанные практики: непрерывная интеграция (Continuous Integration) и непрерывная доставка или развёртывание (Continuous Delivery/Deployment). Простыми словами, это конвейер, через который любое изменение кода проходит одинаковый путь: разработчик коммитит код в Git, автоматика собирает проект, прогоняет проверки и тесты, а затем выкладывает результат на сервер по единому сценарию. Для 1С-Битрикс это означает, что вы перестаёте править файлы прямо на боевом сайте по FTP и переходите к предсказуемым релизам: тот же код, что прошёл проверку на тестовом окружении, атомарно едет на прод. Специфика Битрикса в том, что часть системы — контент, настройки, ядро — живёт не в Git, а в базе данных и в защищённых каталогах, поэтому конвейер строят вокруг кода, а данные и структуру синхронизируют отдельными механизмами.

Почему нельзя просто править файлы на проде по FTP?

Потому что правки на проде по FTP — это работа без страховки. У вас нет истории изменений: непонятно, кто, что и когда поменял, и как вернуться к рабочему состоянию, если сайт «лёг». Нет ревью — ошибка едет сразу на боевой сайт, который в этот момент видят покупатели. Нет тестового прогона — синтаксическая опечатка в PHP роняет страницу с фатальной ошибкой прямо во время редактирования. Нет отката одним движением — чтобы вернуть как было, нужно вручную вспоминать, что вы трогали. На небольшом сайте это иногда сходит с рук, но на боевом магазине каждая такая правка — это лотерея с выручкой. Git и CI/CD убирают эту лотерею: код версионируется, проверяется и выкатывается по повторяемому сценарию с возможностью мгновенного отката.

Что коммитить в Git на проекте 1С-Битрикс, а что игнорировать?

В Git версионируют то, что является кодом проекта и создаётся руками разработчика: каталог /local целиком (свои компоненты, шаблоны, модули, обработчики событий в /local/php_interface), шаблоны сайта, кастомизированные компоненты, миграции структуры и файлы конфигурации окружений (без секретов). Игнорируют то, что либо не является вашим кодом, либо специфично для конкретной среды: ядро /bitrix (оно обновляется штатным механизмом, а не через деплой), каталог загрузок /upload (это пользовательский контент, ему место в резервных копиях, а не в Git), кэш /bitrix/cache и /bitrix/managed_cache, а также реальные настройки подключения к базе — /bitrix/.settings.php и /bitrix/php_interface/dbconn.php с паролями. Правило простое: в Git едет код, одинаковый для всех окружений; данные, кэш и секреты остаются за его пределами.

В чём разница между окружениями dev, stage и prod?

Это три среды с разными задачами. Dev (development) — среда разработчика: здесь пишут и отлаживают код, здесь можно ломать и экспериментировать, данные обычно обезличенные или тестовые. Stage (staging, предпрод) — копия боевого окружения по конфигурации: сюда выкатывают релиз-кандидат перед продом, здесь проходят приёмку, регресс и проверку миграций на свежей копии боевой базы. Prod (production) — боевой сайт, который видят покупатели: сюда попадает только то, что успешно прошло stage. Смысл трёх окружений в том, чтобы любое изменение проверялось в условиях, максимально близких к боевым, до того как затронет реальных клиентов и выручку. Ключевое требование к stage — быть похожим на prod по версии PHP, настройкам веб-сервера и структуре данных, иначе проверка теряет смысл.

Как переносить контент между окружениями, если он в базе, а не в Git?

Никак не переносить автоматически в общем случае — и это принципиальный момент. Контент (товары, заказы, страницы, картинки в /upload) живёт в базе данных и файлах загрузок, а не в Git, и его нельзя выкатывать релизом, потому что на проде он «живой»: пока вы разрабатывали, покупатели оформляли заказы и меняли данные. Направление синхронизации обычно обратное коду: базу и /upload копируют с прода на stage и dev, чтобы разработка и тесты шли на реалистичных данных (предварительно обезличив персональные данные покупателей). А вот изменения структуры — новые свойства инфоблоков, пользовательские поля, опции модулей — это уже не контент, а часть логики, и их переносят вперёд, на прод, через миграции. Разделение «код и структура едут вперёд через Git и миграции, а данные едут назад через дампы» — основа работы с Битриксом в CI/CD.

Что такое миграции структуры в 1С-Битрикс и зачем они нужны?

Миграция — это версионированный сценарий изменения структуры данных, который применяется одинаково на всех окружениях. Проблема в том, что если разработчик руками в админке добавил новое свойство инфоблока или включил опцию модуля на своём dev, то на stage и prod этого изменения нет — код, который на него рассчитывает, там упадёт. Миграция описывает такое изменение как код (добавить свойство PROPERTY с такими параметрами, создать пользовательское поле, установить значение опции) и хранит отметку, что она уже применена. При деплое пайплайн прогоняет непроведённые миграции, и структура на всех окружениях приходит к одному состоянию автоматически, в правильном порядке. Для Битрикса это решают специальные модули миграций из экосистемы, которые умеют работать со свойствами инфоблоков, highload-блоками, пользовательскими полями и опциями модулей.

Как сделать деплой 1С-Битрикс без простоя сайта?

Основной приём — атомарное переключение релизов через симлинк. Новый релиз выкладывается в отдельный каталог (например, releases/2024-03-26-1530), там устанавливаются зависимости и прогреваются нужные вещи, а веб-сервер всё это время продолжает отдавать старый релиз. В финале деплоя одной операцией переключается символическая ссылка current на новый каталог — это происходит мгновенно и незаметно для посетителей, потому что переключение атомарно. Общие для релизов вещи (каталог /upload, реальный .settings.php, логи) выносят в отдельную папку shared и подключают симлинками, чтобы они не копировались с каждым релизом и переживали переключение. После переключения кэш прогревают запросами к ключевым страницам, чтобы первый живой посетитель не попал на «холодную» генерацию. Откат при таком подходе — это обратное переключение симлинка на предыдущий релиз, тоже мгновенное.

Почему обновление ядра Битрикса нельзя делать через тот же деплой, что и код?

Потому что у ядра /bitrix и вашего кода разные владельцы и разные механизмы изменения. Ядро обновляет сам Битрикс через технологию SiteUpdate: система скачивает обновления модулей, применяет патчи и правит собственные файлы и структуру базы по своим правилам. Если положить каталог /bitrix в Git и выкатывать его релизом, вы получите конфликт двух источников правды — обновлятор Битрикса и ваш деплой будут перезаписывать файлы друг друга, а расхождение версий ядра и базы приведёт к трудноуловимым ошибкам. Поэтому /bitrix исключают из репозитория и деплоя, а обновления ядра проводят отдельной, контролируемой процедурой: сначала на копии (stage), с проверкой совместимости и резервной копией, и только потом на проде. По сути, это два независимых потока изменений — ваш код едет через CI/CD, а ядро обновляется штатным механизмом платформы.

Поделиться:

Нужен предсказуемый деплой на 1С-Битрикс?

Настроим Git, окружения dev/stage/prod, миграции структуры и пайплайн CI/CD с деплоем без простоя. Уйдёте от правок на проде по FTP к релизам, которые проверяются на копии боевого сайта и откатываются за минуту.

Игорь Воскресенский

Команда студии B2Bsite. С 2014 года разрабатываем, ускоряем и поддерживаем проекты на 1С-Битрикс: Git и CI/CD, окружения dev/stage/prod, миграции структуры, деплой без простоя, обмен с 1С и инфраструктура для среднего и крупного бизнеса.

← Все статьи блога