How to tell your non-technical customer about Docker, CI/CD, linters, etc.

Sometimes we need to proof somebody importance of basic development stuff. This template will help you to tell about important things for development to your non-technical customer or collegue.
It’s written in Russian. If you need it in English, just ask me in comments :)
Перед самим документом хочу подчеркнуть пару важных вещей:
- относитесь к вашему собеседнику не как к врагу, который тупой и ему надо всё объяснить, а как к партнёру, который поддержит развитие продукта, если действительно поймёт важность описанных вами вещей;
- очень частый аргумент нетехнических людей о ниже описанных вещах звучит так: “Это не влияет напрямую на бизнес”. Помните, что вы перечисляете популярные методологии, инструменты и подходы, ни один из которых не развился бы, если бы реально не влиял на бизнес. Каждая конкретная штука в разработке существует только потому, что она положительно влияет на бизнес;
- данный шаблон подходит только для небольших веб-проектов, которые вскоре столкнутся или уже столкнулись с типичными проблемами превращения небольших продуктов в большие продукты;
- в этом документе конкретные инструменты и подходы приведены для примера, в вашем продукте все может быть совершенно по-другому. Обращайте внимание на подход изложения, а не на ключевые слова. А подход изложения здесь таков, мы идём от целей бизнеса прежде всего. Мы берём наш любимый стафф для разработчика, понимаем, какую ценность он несёт бизнесу и начинаем именно с ценностей. Цели здесь — это как раз ценности для бизнеса, а уже в тексте идёт самый сок;
- в некоторых местах документа допущены специальные неточности, которые не меняют сути предложения, но помогают читающему осознать главную мысль. Такое возможно делать в подобных ситуациях, помните, нам говорили в первом классе, что нельзя делать 2–3, а во втором рассказали про отрицательные числа. Это было сделано для удобства понимания. Здесь тот же подход;
- ожидается, что после прочтения подобного документа у вас будет встреча или созвон с заказчиком / коллегой, где вы подробно обсудите каждый пункт.
Предложения по обновлению инфраструктуры проекта
Для стабильной работы проекта требуется реализовать набор инфраструктурных задач, которые повысят стабильность работы всего сервиса, ускорят разработку, а так же позволят предотвращать внезапные проблемы. Ниже сформирован ряд целей.
Цель: Стандартизация всех окружений
В разработке каждого программного продукта обычно существует несколько окружений. Каждое окружение нужно для того, чтобы запускать проект в той или иной среде. В рамках работы над проектом используются следующие окружения:
- продакшен — конечный продукт;
- staging — окружение, которое существует для презентационных задач и обсуждения развития продукта;
- dev-stand — окружение для разработчиков, которое позволяет им делиться результатами своей работы, а также проводить QA;
- development — окружение локальной разработки каждого специалиста
- CI (будет описано ниже) — окружение запуска автоматизированных задач
Окружение организуются набором конфигураций, например, debugger — инструмент, позволяющий программистам быстрее реализовать задачи, абсолютно не нужен в окружении продакшена. Более того, наличие debugger в продакшене может привести к уязвимостям в проекте. Благодаря конфигурации debugger можно отключить на продакшене и использовать его только там, где он нужен. Примеров таких инструментов и других типов конфигурации огромное множество.
Для того, чтобы качественно управлять окружениями, требуется их стандартизация. Современные команды организуют стандартизацию с помощью Docker. Docker — это инструмент, позволяющий описывать правила того или иного окружения без влияния на соседние. Docker не только позволяет описывать эти окружения, а также создаёт требуемую изоляцию, чтобы в рамках одного окружения работали только описанные правила и никакие другие.
Докеризация помогает в онбординге новых сотрудников в проект. Как правило, время на разворачивание рабочей инфраструктуры проекта на локальных компьютерах разработчиков сокращается в несколько раз.
Задачи для достижения данной цели:
- Создание и тестирование работы докер-образов для разных окружений бекенда (Rails, ActionCable, PostgreSQL, Redis, Prometheus, Grafana, etc.);
- Создание и тестирование работы докер-образов для разных окружений фронтенд-приложения (ReactJS);
- Создание и тестирование работы докер-образов для разных окружений админки.
Цель: Стабильность обновления функциональности
Количество функций проекта постоянно растёт, кроме Функции 1 существуют Функции 2 и 3 . Сама Функция 1 крайне сложна и имеет огромное множество кейсов использования. Чем больше проект содержит функциональности, тем больше растёт сложность изменения и дополнения этой функциональности. Команда разработки совместно с заказчиками должны быть уверены в том, что при обновлении функциональности продукта остальные его части продолжат работать без изменений. Грубо говоря: мы не сломаем то, что уже работает. Почему могут происходить такие поломки? В разработке есть термин “зацепление” или “связанность” (не путать со связностью). Зацепление характеризует насколько архитектура программного кода доступна для изменений. Сильное зацепление приводит к ситуации, когда изменение одной функциональности “цепляет” другую. К сожалению, без дополнительной аналитики зацепление любого программного кода начинает расти. Поэтому все базы исходного кода периодически должны проходить процесс рефакторинга, то есть изменений кода без изменения функциональности продукта для понижения зацепления и улучшения других метрик.
Также для минимизации зацепления и эффективного обновления функциональности продукта используется автоматическое тестирование. Автоматическое тестирование предполагает создания набора авто-тестов (далее тесты), мини-программ, которые автоматически тестируют функциональность продукта. Тесты гарантируют стабильность функциональности при изменениях. Чем больше функциональности тестируется этими мини-программами, тем больше стабильность. Мини-программы ликвидируют человеческий фактор в тестировании, а также ускоряют тестирования программного продукта, потому что программы работают быстрее и точнее людей. Тесты помогают проводить рефакторинг программного кода, убирая надобность ручного тестирования в тех местах, которые эти тесты покрывают.
Для нашего проекта необходимо реализовать и поддерживать два вида тестов:
- end-to-end тесты. Эти тесты работают автоматически в браузере. Изображая пользователя, они используют функции программного продукта и проверяют реакцию на те или иные события;
- интеграционные тесты. Эти тесты будут тестировать только бекенд-часть системы. Они ускоряют разработку бекенда, так как результат работы бекенда — это данные в формате JSON (или ином машинном формате), человеку очень сложно читать машинный формат данных, когда как программа легко с этим справляется, упрощая и ускоряя тестирование бекенд функциональности. В нашем проекте эти тесты будут частично закрывать вопрос по документации к продукту. Будут использоваться специальные модули, результатом работы которых является декларативное описание данных, которые бекенд принимает и возвращает. Эта документация крайне полезна для фронтенд — разработчиков, а так же для бекенд разработчиков, чтобы быстро понимать, что делает та или иная функция.
Задачи для достижения данной цели:
- Создание тестового окружения для end-to-end тестов;
- Покрытие 80% функциональности тестами;
- Создание окружения для интеграционных тестов;
- Покрытие 80% функций бекенда.
Цель: Предотвращение технических проблем инфраструктуры
Каждый программный продукт — это развивающаяся система, работа которой зависит от множества факторов. В случае с веб-приложениями очень важным фактором является стабильность работы серверов. Мощности и характеристики любого сервера ограничены, и крайне сложно предсказать, когда развитие продукта упрётся в эти ограничения. Ситуации, когда потребление продукта упирается в ограничения серверов, приводят к тому, что конечные пользователи не могут получить доступ к функциям, и могут не получить услуг сервиса из-за их недоступности. Безусловно, можно сразу арендовать очень мощное оборудование, но это дополнительные расходы, которых можно избежать, если использовать мониторинг. Мониторинг работы серверов позволяет наблюдать в режиме реального времени расход ресурсов, которые имеют сервера, и предсказывать увеличение этих расходов.
Современные инструменты мониторинга позволяют проводить сложный анализ ресурсов сервера и предупреждать команду разработки о приближении к ограничениям. Это позволит своевременно принимать решения по развитию инфраструктуры до появления проблем.
Также, мониторинг позволяет команде разработки быстрее находить источник неочевидных проблем. Так как наш продукт — это набор разных инструментов и модулей, порой непонятно, какой из них мешает стабильной работе системы. Правильная настройка мониторинга позволит команде разработки выяснять это “в один клик”, тем самым ускорять решение проблем.
Задачи для достижения данной цели:
- Установка и настройка инструментов мониторинга (Prometheus, Grafana, Errbit, etc.);
- Настройка коммуникации между этими сервисами и рабочими чатами команд.
Цель: Достижение уверенности в сохранности данных
Данные для любого программного продукта — это один из главных ресурсов его развития. При правильном использовании контактов клиентов и аналитики их действий они позволяют повышать конверсию, удержание клиентов, а также привлекать новых.
В этой связи нужно гарантировать их сохранность. Сейчас основные данные продукта лежат на сервере в единственном экземпляре. В случае, если с дата-центром, в котором находится наш сервер что-то случится или команда разработки допустит ошибку при обновлениях, данные могут быть утеряны. В этой связи требуется организовать периодическое копирование данных в несвязанное с основным сервером хранилище — бекапы.
Бекапы при правильной настройке гарантируют сохранность данных, даже в случае “полной смерти” основного сервера.
Бекапы нужно тестировать. Не смотря на то, что функция бекапов кажется простой (просто скопировать), со временем может привести к тому, что система не верно скопировала данные. Например, если данные передавались по сети, любой обрыв сети может привести к потере данных из бекапа. И в момент восстановления данных окажется, что у нас нет качественно сохранённых данных.
Для повышения гарантии того, что бекапы работают, нужно будет реализовать сценарий, при котором каждый новый бекап сразу будет разворачиваться на dev серверах для разработчиков без критически важных данных (контактов пользователей и т.д.). Учитывая, что с dev серверами разработчики активно работают, шанс, что они заметят неконсистентность данных довольно большой.
Для повышении гарантии того, что в бекапах хранятся консистентные критические данные (контакты пользователей и т.д.) мы можем создать несколько тестов, которые будут сравнивать эти данные с продакшеном после копирования и по определённым условиям выяснять, что все данные верно сохранились.
Задачи для достижения данной цели:
- Выбор способа создания бекапов данных;
- Выбор алгоритма создания бекапов (каждый день, каждый час, использовать функции хостинга или самостоятельно реализовать и т.д.);
- Программирование сценария выгрузки обновлённых бекапов на стенды разработчиков;
- Создание тестов для проверки критических данных.
Цель: Ускорение разработки
Как показывают исследования программисты больше читают программный код, чем пишут. В этой связи скорость чтения и понимание программного кода — это важная метрика для ускорения разработки. Также очень часто программисты читают не свой код или свой код, но который писали давно. В обоих случаях для быстрого прочтения и понимания кода нужно, чтобы он был понятным. Языки программирования Ruby и Javascript, на которых разрабатывается наш продукт, являются динамическими. Они позволяют очень быстро реализовать функциональность без большого количества кода, но такая динамичность кода приводит к тому, что читается он иногда сложно.
Решением этой проблемы является конвенция написания кода. Конвенция написания кода — это набор правил, которые обязаны выполнять все программисты на проекте. Тем самым мы приходим к ситуации, когда все разработчики пишут программный код в одном стиле, а значит его легче читать. За ускорением чтения, ускоряется и разработка в целом.
Проверки соответствия кода конвенциям можно автоматизировать с помощью линтеров, специальных программ, которым можно описать конвенцию написания кода, те в свою очередь будут “читать” весь код и обращать внимание разработчиков на несоответствия.
Учитывая, что сейчас в проекте не используются линтеры, требуется привести всю кодовую базу к выбранной конвенции. Переписывать весь код для решения этой задачи нелогично, поэтому есть предложение делать это итеративно, например, после покрытия тестами определённой функциональности провести рефакторинг этой функциональности, уменьшив тем самым зацепление и параллельно приведя конкретную функцию к конвенции кода. Можно выбрать другой итеративный путь.
Задачи для достижения данной цели:
- Выбор конвенции написания кода;
- Настройка линтеров для этой конвенции;
- Выбор итеративного пути для приведения всей кодовой базы к конвенции.
Цель: Автоматизация стандартных задач для ликвидации человеческого фактора при исполнении стандартных задач
Проект YOUR_PROJECT вырос до состояния, когда нужно автоматизировать стандартные процессы разработки: запуск тестов, анализаторов ошибок кода, деплой на сервера и т.д. Для этого используются системы непрерывной интеграции и доставки обновлений (CI/CD). Грубо говоря, мы передаём часть задач разработки машинам.
Главный инструмент, который следует использовать для этой задачи — это Gitlab CI. Он гарантирует нам возможность использовать бесплатно ограниченные ресурсы для запуска наших задач внутри системы, а также, когда нам перестанет хватать стандартных ресурсов для выполнения задач, подключить дополнительные сервера, где эти задачи будут исполняться.
Задачи для достижения данной цели
Автоматизирование следующих задач:
- Прогон автоматических тестов;
- Запуск анализаторов кода (линтеров);
- Деплой обновления на сервера: продакшн, staging, dev-stand.
Цель: Эффективная коммуникация в команде
Все перечисленные выше инструменты, сервисы и подходы в дополнении с таск-трекерами, приводят к тому, что вокруг команды разработки существует инфраструктура и много информации о системе. Для управления этой информацией и упрощения её использования применяются чат-боты. Чат-боты собирают данные с сервисов, которые помогают разработчику и распределяют информацию по чатам проекта, давая информацию именно тем, кому она нужна.
Такой подход увеличивает шанс того, что команда разработки получит важную информацию в нужный момент, а также, что информация не потеряется в наборе сервисов и инструментов.
Задачи для достижения данной цели:
- Выбор сценариев использования чат-ботов;
- Подключение чат-ботов к сервисам.
Magic!
Скорее всего документ будет обновляться.