Обложка статьи «DevOps или Как освободить многих разработчиков в один клик»

DevOps или Как освободить многих разработчиков в один клик

Александр Биденко

Александр Биденко

Frontend Team Lead агентства-интегратора MST

Кто мы?

Мы – агенство-интегратор, занимающееся разработкой сайтов, программного обеспечения, их сопровождением, рекламой, дизайном и многим другим. И за каждой работой стоит целая команда талантливых специалистов, которая трудится для того, чтобы новая технологическая идея достигла конечного потребителя.

Как мы создаем?

Любая идея проходит длинный путь формализации, визуализации, реализации в конечном продукте. И вот, проработав долгие месяцы, команда создала новый технологический шедевр и любуется им на своем устройстве. Но конечная ли это цель?

Что дальше?

Создав новый продукт, разработчики видят его лишь на своем персональном компьютере. При грамотной настройке получится запустить его еще на паре устройств в локальной сети. Но ведь это не то же самое, что запущенное приложение на руках у конечного пользователя. Путь до потребителя оказывается куда сложнее. Необходимо загрузить приложение на публичный сервер, привязать доменное имя, чтобы пользователи не запоминали набор цифр через точки. А еще и про безопасность пользователя забывать нельзя никогда. И даже после всего этого заказчик может захотеть протестировать отдельную новую функцию на сайте. Но только так, чтобы пользователи до релиза об этом не узнали. И тут команда разработчиков расходится по рабочим местам и снова все хватаются за свои талантливые головы.

В чём заключается проблема?

Необходимо запустить наше приложение на публичном сервере, привязать к нему доменное имя, защитить шифрованием, создать возможность быстрого и стабильного обновления и при этом не сойти с ума. Сложностей добавляет тот факт, что сервер – это удаленный компьютер с минимальным графическим интерфейсом. А все разработчики сейчас заняты реализацией новой функции, которую попросили добавить вот совсем недавно.

Решение проблемы!

Именно для таких проблем и существуют различные технологии DevOps. Они и позволяют  решать проблемы поэтапно. Для начала нам нужно развернуть приложение на публичном сервере. И очень хотелось бы сделать это один раз, так, чтобы вручную процедуру повторять потом не приходилось.

На помощь приходят технологии CI/CD, которые идут в комплекте с популярными репозиториями по типу GitHub или Gitlab. Мы у себя используем Gitlab, а значит, для работы необходимо настроить файл .gitlab-ci.yml. Пишем необходимую конфигурацию, загружаем в репозиторий… И ничего не работает. Бэкенд просит интерпретатор своего языка, еще базу данных что-то найти не смог. А фронтенд просто не смог скомпилировать, т.к. не нашел Node.js.

Проблема следующая: как настроить все необходимое программное обеспечение? А если у нас два приложения и каждое хочет свою базу данных? А если надо оперативно сменить сервер? Есть проблема — есть решение!

На помощь приходит технология контейнеризации. Самое известная ее реализация – Docker. Это как очень облегченная версия виртуальной машины, которая будет содержать в себе все необходимое для работы приложения, но ничего больше. Оборачиваем каждое приложение, базу данных и остальные составляющие в отдельный контейнер. Настраиваем каждый из них так, чтобы было все нужное для работы. Обновляем конфигурацию деплоя и – пробуем. Что-то заработало, приложения запустились на сервере, но теперь увидеть результат можно только введя IP адрес и порт. Не очень удобно.

Нам нужна возможность использовать доменные имена и чтобы по нужному имени открывалось нужное приложение. Сами доменные имена направить на сервер не сложно – достаточно прописать нужные записи DNS A и AAAA. Но сервер еще не поймет, чего мы от него хотим. Проблему направления доменного имени на конкретный сайт решают веб-серверы. Вот только у нас много приложений, у всех своя специфика работы. А еще разработчики иногда хотят что-то менять в их настройке — то редирект добавить, то страницу скрыть. Значит нужно добавить собственный веб-сервер как контейнер в каждое приложение. Добавили. Опять стало лучше, но теперь или в браузере нужно вводить доменное имя и порт, или несколько веб-серверов отказываются запускаться одновременно на портах 80 и 443.

Создадим отдельный контейнер с веб-сервером, который будет принимать все запросы на сервер и самостоятельно выяснять, какому приложению принадлежит доменное имя и отдавать запрос ему. Вроде бы с этой задачей также справился бы nginx. Но вспоминаем про следующую проблему – безопасность. А именно нам нужно добавить сертификат SSL(TLS) и возможность безопасного подключения по https-протоколу. Можно настроить генерацию сертификатов, но это занимает время; можно создавать вручную – и это занимает ещё больше времени. Решение нашлось в виде веб-сервера Сaddy – он включает в себя чуть больше функций, чем nginx, в частности, сам генерирует сертификаты безопасности и устанавливает только безопасное подключение к каждому приложению. Сам обновляет сертификаты, и, по сравнению с nginx, настраивается максимально просто.

Реализуем последний контейнер с веб-сервером Caddy, пропишем в нем доменные имена, добавим для красоты www-редиректы, и укажем ему, какое доменное имя на какой контейнер с приложением должно ссылаться. Далее запрос обработает внутренний веб-сервер приложения и перенаправит запрос на наше приложение. И совсем в целях перфекционизма закроем всем приложениям внешний доступ в обход нашей системы, реализуя внутреннюю связь исключительно внутри виртуальной локальной сети.

А для того, чтобы можно было заказчику демонстрировать отдельные функции в нашем сервисе, добавим возможность разработчикам создавать разные версии приложения. Разные версии – разные контейнеры. Разные контейнеры – разные поддомены, обрабатываемые одним веб-сервером, который всегда найдет нужную версию сайта и покажет пользователю именно ее. Заказчику понравилось? Автоматически очистим все лишнее после закрытия merge request в репозитории. Все работает, все довольны.

Специалист DevOps заканчивает последний этап всей этой настройки, и в этот момент разработчики приложения завершают ту самую последнюю функцию, которую попросили доработать перед релизом. Разработчик создает новую ветку в репозитории, загружает туда свои изменения и создает merge request. Далее Gitlab CI, деплой на сервер, поднятие нового контейнера, проксирование уникального поддомена. Как? Пару минут и уже можно показывать заказчику? Конечно он доволен, а значит merge request можно закрывать. Далее идёт подчистка временного сайта, обновление основного сайта, перезапуск контейнера, и в то же мгновение все пользователи интернета могут видеть обновление на своем любимом сайте и не бояться за свою безопасность и стабильность работы приложения. А трудящиеся специалисты опускают свои уставшие головы и с чистой совестью идут отдыхать.