Введение
В данной статье описан мой опыт по настройке одного из этапов разработки, связанного с необходимостью тестирования написанного кода на виртуальной машине от битрикс. Для понимания статьи необходимо базового знать, что такое menu.sh в bitrixVM и принцип работы Gitlab CI и, соответственно, что описано в файле .gitlab-ci.yml.
В качестве вступления будет немного лирики. Если все предпосылки не интересны, можно сразу начинать читать с основной части по настройке.
Сейчас на слуху практики DevOps, CI/CD и прочие штуки, которые ещё не все люди воспринимают всерьёз. В моём же случае максимум, чем приходилось заниматься из этой области – это установка и настройка Gitlab runner на простых проектах на битрикс с тремя контурами – “прод”, “препрод” и “тест”, где runner выполняет git pull из нужной ветки при коммите. Получился самый простой и примитивный pipeline. И по большей части этого всегда хватало – разработчикам или сисадминам не надо ходить руками на сервер, чтобы выкатить код, а всё остальное делали тестировщики на тестовом или препродуктивном контуре.
Но можно было бы навсегда остаться где-то в прошлом, так и не попробовав чуть большего, что может предоставить Gitlab и прочие CI системы. Всё это было не нужно, пока не появился крупный проект, где процесс разработки стал куда более сложным, а тестировать несколько фичей на одном единственном контуре стало затруднительно. И вот тут-то все и вспомнили про практики DevOps, автоматизированное тестирование и прочее.
Мне была поставлена задача настроить автоматический деплой площадок\контуров\среды – называйте, как угодно, на которых независимо можно было бы тестировать каждую ветку (фичу).
Основная часть
Из общей базы у меня были лишь поверхностные знания, как это примерно должно работать из различных статей на хабре. Отсутствие знакомых, кто бы мог подсказать, как делать всё правильно, немного тормозило меня и шло вопреки перфекционизму – хотелось сделать хорошо и правильно, но я не знал, с чего начать.
В конечном итоге, начитавшись документации Gitlab, родилась идея, в основе которой заложено использование виртуальной машины от битрикс, где уже по большей части всё готово и настроено, нужно лишь внести немного автоматизации и настроить процесс интеграции с Gitlab.
Алгоритм развертывания площадки следующий:
- Есть разрабатываемый проект;
- Возникает потребность в новом функционале;
- Разработчик ветвится от основной ветки;
- В ветке с именем feature/01 разрабатывается новый функционал;
- Возникает потребность независимо от других задач протестировать код из feature/01;
- Разработчик открывает merge request;
- При открытии мержа создаётся environment – копируются файлы и база с эталона (прода), раскатываются конфиги веб-сервера и бд, а ветка в директории проекта переключается на feature/01;
- environment представляет собой обычный сайт с нужным функционалом из feature/01, который создается при выполнении определенного этапа из .gitlab-ci.yml, и по сути и является конечной целью.
Под капотом пунктов 5-7 кроется bash и немного магии, о которой расскажу более подробно.
Сервер
И всё начинается с сервера — необходимо подготовить тачку, на которой непосредственно будут разворачиваться необходимые сайты для тестирования. Условно этот сервер будет иметь hostname srv-bx-qa
- На сервере установлено битрикс-окружение (apache, nginx, php, mysql – всё на одной ВМ);
- Для скорости добавлен SSD-диск с разделом под БД и файлы и смонтирован по пути /mnt/u01;
- В файле /root/.bash_profile закомментирована строка #~/menu.sh, которая вызывает автоматический запуск menu.sh при открытии оболочки – это мешает выполнению команд gitlab runner, а потому сразу отключается;
- На самом сервере выполнена настройка и запущен gitlab runner с тэгом
qa-env
- С сервера srv-bx-qa настроен беспарольный доступ по ssh на сервер эталонный контур (прод), для копирования файлов через rsync – ядро и прочие необходимые файлы для битрикса будут эталонной основой для нового контура.
bitrix-env
Развертывание целевого environment (далее – контур или среда) происходит штатными средствами bitrix-env, только в отличие от ручного метода (скрипт menu.sh) используется API, описанный в документации.
Например, создание сайта test1 через API будет выглядеть следующим образом:
/opt/webdir/bin/bx-sites -a create -s site1 -d site1_db -t kernel -u site1_user -p 'site1_user_pass' -r /mnt/u01/ext_www/site1
Аналогично и удаление:
/opt/webdir/bin/bx-sites -a detete -s site1
Всё вышеописанное заполняется обычно вручную при классическом создании\удалении сайта через menu.sh, в результате чего генерируются конфиги для веб-серверов и БД. А значит, есть возможность использовать автоматизацию при развертывании сайта, указывая динамически создаваемые имена. Например, в какой-нибудь CI-системе — Gitlab в данном случае, т.к. он используется в качестве СКВ.
Gitlab
В Gitlab располагается репозиторий исходного проекта, в корне которого файл .gitlab-ci.yaml выполняет описанные в нём инструкции при различных событиях (commit, merge request & etc) посредством gitlab-runner, который установлен на целевом сервере srv-bx-qa.
Основные переменные
В .gitlab-ci.yaml используются встроенные переменные окружения внутри самого gitlab, на основе которых создаются доменные имена сайтов, имена БД, пользователей и т.д.
$CI_PIPELINE_SOURCE
– указывает, что происходит событие “merge_request_event”, которое является условием срабатывания pipeline;$CI_COMMIT_REF_NAME
– имя ветки или тэга;$CI_COMMIT_REF_SLUG
– имя ветки или тэга, ограниченное 63 байтами и исключающее символы, которые не могут быть использованы в URL. Применяется для создания доменного имени на основе имени ветки.
На основе трех вышеописанных переменных создается уникальное доменное имя для будущего сайта.
Создание сайта
В .gitlab-ci.yaml описана job с именем “review” – она-то и будет создавать новый сайт:
review:
stage: review
script:
- /opt/scripts/deploy_env.sh create
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
allow_failure: true
environment:
name: review/$CI_COMMIT_REF_NAME
url: https://$CI_COMMIT_REF_SLUG.tech.domain.ru/
on_stop: stop_review
auto_stop_in: 4 days
tags:
- qa-env
Во фрагменте “кода” выше при выполнении job “review” будет выполнен скрипт /opt/scripts/deploy_env.sh create
, который выполнит установку и подготовку серверного окружения. Условием срабатывания данной job является открытие мерж реквеста.
Помимо создания и подготовки сайта на самом сервере через bash-скрипт, создается environment – сущность уже в самом гитлабе, которая позволяет управлять непосредственно созданной площадкой в данном случае.
environment имеет имя, URL, по которому доступен сайт, и условия удаления. В данном случае среда автоматически самовыпилится через 4 дня, а для штатного удаления используется отдельная job с именем “stop_review”:
stop_review:
stage: review
variables:
# не подтягивать изменения. Необходимо, если ветка удалена
GIT_STRATEGY: none
script: /opt/scripts/deploy_env.sh delete
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
when: manual
allow_failure: true
environment:
name: review/$CI_COMMIT_REF_NAME
action: stop
tags:
- qa-env
Наименование stage здесь должно быть аналогичным предыдущему, т.е. “review”. bash-скрипт /opt/scripts/deploy_env.sh delete будет при выполнении удаляет раскатанный сайт и всю созданную конфигурацию.
Отличительной особенностью является условие “manual” – в данном случае данная job будет выполнена при нажатии кнопки в самом gitlab, удалении environment или закрытии мерж реквеста. Это будут использовать тестировщики: сайт раскатывается автоматически, тестеры прогоняют свои тесты, а потом удаляют площадку вручную после завершения тестирования. Да, до автотестов ещё не дошли и люди ходят руками по сайту в поисках багов
В разделе CI / CD -> Jobs будет видно два задания:

passed – это первая часть – создание сайта и всего необходимого, выполнилась при открытии мержа
manual – автоматически появляется и ожидает исполнения, т.е. ручного нажатия на кнопку “Play”
Проверить и открыть среду для тестирования в браузере можно по пути Opertions→Environments в интерфейсе Gitlab.
bash-скрипт
Создание и удаление сайта выполняется через функции несложного скрипта на bash, полный код представлен на github
Настройка проксирования
В результате создания среды доменные имена будут вида feature-01-your-qa.domain.ru. Для проксирования используется Nginx, слушающий запросы вида *.your-qa.domain.ru и с настроенным wildcard-сертификатом.
Заключение
В результате вышеописанных действий поставленная задача выполнена – тестировщики теперь имеют возможность тестировать ветки в изолированной среде и не мешать друг другу.
Вопрос лишь в том, насколько всё сделано правильно. Мне всегда кажется, что больше какая-то кустарщина. В любом случае, это был первый блин, и пока не ясно, вышел ли он комом, но в результате выполнения данной задачи были рассмотрены различные возможности по организации доставки кода и настройки площадок. Как известно, нет пределу совершенства, поэтому возможности Gitlab будут изучаться дальше и апробироваться на какие-то конкретных кейсах.
Более подробную информацию можно получить в документации гитлаб, а битрикс в данном случае – лишь частный случай, тем не менее, документация у них тоже вполне себе хорошая.
UPD. Спустя некоторое время использования, вылезли подводные камни придуманного решения:
1. Условие развёртывания контура (напомню, что это происходит при открытии мержа) только мешает, т.к. не всегда требуется раскатка площадки тестирования, а потому условие было перепилено на ручное в .gitlab-ci.yaml:
variables:
GIT_STRATEGY: none
review:
stage: review
script:
- "/opt/scripts/deploy.sh create"
environment:
name: review/$CI_COMMIT_REF_NAME
url: https://$CI_COMMIT_REF_SLUG.domain.ru/
on_stop: stop_review
auto_stop_in: 1 days
rules:
- if: '$CI_COMMIT_REF_NAME =~ "feature" && $CI_PIPELINE_SOURCE == "web"'
allow_failure: true
tags:
- qa
И теперь пайплайн запускается вручную при необходимости – так даже удобнее, чем первоначальная идея. Но всё зависит от конечной цели.
2. И второй нюанс, который поставил крест на всей идее для полноценного использования: при наплыве тестировщиков развертывание сайтов становится крайне медленным и job`ы зависают. У меня в скрипте очень примитивные проверки статусов сайтов в цикле, и пока не истинны условия для выхода из цикла, job будет висеть. А условиями является проверка статуса вызова API и наличия\отсутствия конфигов.
В итоге не совсем понятно, где проблема: при ручном использовании menu.sh хотя бы с одной фоновой задачей, он уже всегда подтормаживал, а с примитивной автоматизацией и несколькими пользователями, которые постоянно раскатывают\удаляют площадки тестирования, и подавно. Или же диски не вывозят (на самом деле используется обычный SATA SSD с другими проектами ещё в нагрузку). Ну, и вся идея стала не очень удобна для использования, но был получен интересный опыт. Возможно, как дойдут руки, эту связку попробую применить уже к другому проекту на kubernetes.
У reg.ru есть возможность получить облачный сервер для развертывания bitrixVM, можно посмотреть подробнее по этой ссылке (реферальная): https://www.reg.ru/vps/cloud/?rlink=reflink-6744079