Конфигурация NodeJS приложений

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

Конфигурация приложения – это все, что может меняться между развёртываниями (среда разработки, промежуточное и рабочее развёртывание). Это включает в себя:

  • идентификаторы подключения к ресурсам типа базы данных, кэш‑памяти и другим сторонним службам;
  • регистрационные данные для подключения к внешним сервисам, например, к Amazon S3 или Twitter;
  • значения зависимые от среды развёртывания такие, как каноническое имя хоста.

Простой путь

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

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

Правильный путь

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

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

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

Все это и больше

Итак, в большинстве приложений есть три варианта развёртывания:

  • боевое, конфигурация передаётся через переменные окружения;
  • локальное, конфигурация передаётся через .env файлы;
  • тестовое, конфигурация передаётся из констант внутри кода.

Хочется иметь способ удобно работать с этими тремя (да и вообще любыми) случаями. Такой способ — создание некой абстракции над конфигурацией, конкретная реализация которой будет различаться в зависимости от окружения.

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

@solid‑soda/config

В мире PHP есть отличное решение — Symfony Config Component. Эта библиотека умеет делать все что нужно для конфигурации приложений. Она вдохновила меня на создание @solid‑soda/config— абстракции над конфигурацией, которая предоставляет удобный и безопасный интерфейс для доступа к параметрам в Node.js.

Библиотека включает в себя набор вариантов конфигурации (.envфайлы, любые другие файлы, переменные окружения, константы внутри кода) и общий для них интерфейс. При необходимости можно легко добавить свою реализацию и использовать её как встроенную.

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

Конфигурируйте!

Конфигурация приложений — один из самых важных аспектов разработки. Это место, где постоянно происходят утечки секретных данных, тормозится процесс внедрения непрерывной доставки, случаются сложно отлавливаемые рантайм‑ошибки. Забота об этом — необходимость при разработке любого приложения.