Создание изолированного окружения для разработчиков Bitrix в Docker

На работе возникла необходимость сделать для разработчиков Bitrix песочницу, где бы они могли проводить свои эксперименты в рамках одного проекта. Для этого была установлена ОС CentOS v7.4 + развёрнуто окружение BitrixEnv v7.2.2 (MySQL, Nginx, Apache – всё на одном серваке), созданы сайты (vhosts) через это окружение с отдельными директориями для каждого разраба вида /home/bitrix/ext_www/develop1.company.ru, а также установлен Docker v18.06.

Исходные данные следующие:
– контент в директориях разработчиков и MySQL база синхронизируются с тестовым контуром (сервер, куда разрабы выкатывают результат после обкатки в песочнице), изначально у всех всё одинаковое.
– синхронизация между песочницей и тестовым сервером не должна вызывать у разрабов трудностей, по сути это одна команда или скрипт для запуска синхронизации.
– все разработчики ходят по sftp\ssh под своими учетками, права у которых аналогичные учетной записи Bitrix. То есть имена учеток разные, а UID и GUI аналогичные учетке Bitrix.
– каждый разработчик должен иметь доступ только к своей песочнице (а так как у всех учеток права идентичны Bitrix и по сути одинаковы, будет использоваться Docker для разграничения).

Рисунок 1 – схема подключения разработчиков

На рис. 1 схематично изобразил принцип подключения: разработчик develop1 подключается в Docker контейнер, куда ему выдан доступ по ssh, а уже в контейнер подмонтированы реальные файлы из директории его сайта develop1.company.ru, где он волен делать с ними, что пожелает. К базе данных также открыт порт из контейнера. По такому принципу работают и все остальные.

Далее непосредственная реализация.

Перед началом работ необходимо убедиться (netstat -tulpn | grep 3306), что MySQL сервер хост-машины слушает TCP-сокет (директива bind-address 0.0.0.0 в /etc/my.cnf в разделе [mysqld]) на TCP порту 3306, а firewalld выключен (systemctl stop firewalld) и не запустится при ребуте сервера (systemctl disable firewalld) – фаервол лучше не отключать, а разрешить правила, не делайте так в продакшене.

Создается Dockerfile с таким содержимым:

[code]

FROM centos:7
RUN yum -y install epel-release openssh-server openssh-clients rsync nano net-tools mysql sudo
RUN yum -y install npm
EXPOSE 22
COPY start.sh /
CMD ["sh", "/start.sh"]

[/code]

Пояснение: простейший файл, который берет за основу Centos v7 и производит в образ докера установку минимального набора софта, который требуется для реализации задумки + для самих разработчиков. Помимо установки пробрасывается 22 порт и стартует при создании контейнера скрипт start.sh:

[code]
#!/bin/sh
echo "Создаю юзера bitrix..."
adduser -d /home/bitrix -g 600 -M -N -o -u 600 bitrix
echo "Создаю группу bitrix..."
groupadd -g 600 bitrix
echo "Создаю юзера разработчика..."
adduser -g 600 -M -N -o -u 600 ${USER}
echo "Создаю пароль..."
echo -e "${PASS}\n${PASS}\n" | passwd ${USER}
# запуск npm от sudo для установки gulp
echo "${USER} ALL=NOPASSWD: /bin/npm" >> /etc/sudoers
/bin/cd /home/${USER}
# установка gulp в директорию с сайтом
sudo /bin/npm install --global gulp
echo "Запускаю ssh демон"
/usr/bin/ssh-keygen -A
/usr/sbin/sshd -D
[/code]

Пояснение: простейший файл, который берет за основу Centos v7 и производит в образ докера установку минимального набора софта, который требуется для реализации задумки + для самих разработчиков. Помимо установки пробрасывается 22 порт и стартует при создании контейнера скрипт start.sh:

Теперь возникает другой вопрос – как разрабы будут попадать из внешки к нам внутрь контейнера по ssh? Классический проброс портов приходит на помощь.

Рисунок 2 – проброс ssh в контейнер

Разработчик стучится по доменному имени с выданным ему ssh портом (30122, 30123, 30124), а далее уже происходит проброс на сервер-песочницу с vhosts, а тот в свою очередь пробрасывает уже в нужный контейнер каждого разработчика (30022, 30023, 30024).

Немного разобравшись с теорией и как это будет работать, можно приступить к сборке образа Docker (обратите внимание, что команду нужно выполнять в директории, где лежит Dockerfile и иже с ним связанное, а в конце названия образа точка через пробел):

docker build -t ssh_image .

Образ с именем ssh_image создан, осталось запустить контейнер:

docker run -d -p 30022:22 -v \
/home/bitrix/ext_www/develop1.company.ru:/home/develop1 -v \
/home/bitrix/.ssh/:/opt/bitrix_key \
-e "USER=develop1" -e "PASS=AABMlf3V" \
--name develop1 -h develop1 -it ssh_image

Вышеописанной командой мы запускаем контейнер в фоне (-d), пробрасываем порт 30022 на хост машину (-р) (в контейнере ssh слушает на дефолтном 22), подмонтируем имеющуюся директорию с файлами сайта для пользователя develop1 с хост машины и пробросим в контейнер (-v) по пути /home/develop1. Помимо директории с сайтом, пробрасывается .ssh для дальнейших действий по синхронизации актуальных данных с тестового сервера проекта и базы данных MySQL.  Флаг -е устанавливает значения переменным окружения, которые будут доступны внутри контейнера.

Если запустить docker ps -a, то в фоне должен быть контейнер с именем develop1 в состоянии up и с проброшенным портом 30022:22

И в завершение схемы, изображенной на рисунке 2, остается проброс портов на роутере (iptables):

iptables -t nat -A PREROUTING -p tcp -d <external_IP> --dport 30122 -j DNAT --to-destination <IP сервера с Docker на борту>:30022

Ещё раз простыми словами. Схема получается такая: разработчик идёт на адрес вн.адрес по внешнему порту 30122, который пробрасывается на внутренний адрес песочницы <IP> с портом 30022, а далее проброс идёт уже в контейнер на локальный порт 22 по умолчанию.

По итогу имеем контейнеры, которые выступают в роли изоляции, и пользователи не могут попасть в чужие директории в /home/bitrix/ext_www, при этом для разрабов всё прозрачно и они знать не знают о каких-то там докерах и прочем.

Отмечу также, что разработчиков немного, поэтому пробросы делал на каждого ручками. Но в случае чего всегда можно пробросить групповой. Также для удобства все команды запуска контейнеров с уникальными логопассами я скопировал, и в случае чего не надо будет тратить врем яна набор длинной команды по запуску контейнера.

Синхронизация с тестовым сервером проекта

Рисунок 3 – схема обновления данных с  тестового сервера в песочницы разработчиков

На основном тестовом сервере, на котором ведется разработка, выкатили изменения + изменились поля в БД проекта. Разработчики просят обновить им среду разработки и синхронизировать все файлы с тестом. Каждый раз таким заморачиваться – можно с ума сойти, всё должно быть максимально автоматизировано.

Синхронизация БД

ssh -i /opt/bitrix_key/id_rsa bitrix@<IP тестового сервера> \
mysqldump -u bitrix0 -p'пароль битрикса в БД' <имя БД> | mysql -u \
bitrix0 -p'пароль битрикса в БД' -h <IP сервера-песочницы> \
<имя БД>_develop1

Так как база данных на тестовом сервере имеет такие же доступы, что и локальная для учетной записи bitrix0, то можно смело по ssh посылать команды для создания дампа и его раздампливания на лету уже на сервере с песочницами.

Синхронизация файлов

rsync -e "ssh -i /opt/bitrix_key/id_rsa" -av \ 
--exclude='bitrix/php_interface/dbconn.php' \
--exclude='bitrix/.settings.php' --exclude='upload/' \
--exclude='bitrix/cache' --exclude='bitrix/managed_cache' \
--delete --progress bitrix@10.16.0.11:/home/bitrix/www/ ./

После обновления БД с теста, нужно стянуть оттуда из общей папки /home/bitrix/www файлы. rsync нам в этом помогает:
исключаются директории с кэшем и файлами-настрайками БД, удаляется всё в текущей директории и стягивается всё оставшееся с сервера.

Ваш комментарий будет первым

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *