Допустим я делаю веб-приложение, которое использует какой-то API или просто работает с базой данных. Я хочу выложить исходные коды приложения в открытый доступ, но как быть с секретными данными, такими как ключи API, пароли к БД и SMTP?
Я могу написать в readme, что конфигурационный файл такого-то типа вам придется создать руками, но хочется собирать проект и отправлять его в продакшн из git репозитория, который хостится, например, на github.
Особенно интересно было бы прочитать ответы на примере Java технологий, потому что я делаю Java веб-приложение.
Ответ
В самом общем случае, в общедоступный репозиторий кладут конфиг-файл, в котором нет паролей и хостов, которые вы не хотите скомпрометировать. Пишут какие-нибудь дефолтные значения (например, example.com или 12345), в комментариях или документации описывают, что нужно подставить, чтобы работало. Реальные же конфиги держат в недоступном для посторонних месте (например, приватном репозитории) и подкладывают во время деплоя в продакшн.
Обычно конфигурацию стараются вынести из архива с приложением, чтобы его не перепаковывать его при деплое. Это можно сделать как захардкодив имя конфига, и ожидая его найти в папке с приложением или каком-нибудь другом заранее известном месте, так и требуя от пользователя указывать путь к конфигу в аргументах JVM при запуске.
Также распространённым вариантом является частичное переопределение конфигов (которое очень хорошо работает, если конфиги - файлы properties). В архиве с приложением лежит полный конфиг, в котором все секретные параметры заменены дефолтными значениями, а извне лежит конфиг, в котором указаны реальные значения только для секретных параметров. Приложение сначала читает конфиг, который в него зашит, потом - внешний, и переопределяет совпадающие параметры. Так мы избавляемся от необходимости полностью копировать конфиг в приватный репозиторий и постоянно синхронизировать его с публичным.
Если ваше приложение написано на Spring Boot, то всё это вы получаете из коробки. Spring Boot умеет подтягивать внешние конфиги из кучи мест и позволяет управлять загружаемыми конфигами при помощи профилей.
Также в семействе проектов Spring есть Spring Cloud Config, работающий в связке с Spring Cloud Config Server. Сервер конфигурации может подтягивать конфиги из множества источников (в том числе из репозитория Git) и отдавать их через REST API. Клиент (ваше приложение) подтягивает значения свойств через стандартные аннотации Spring @Value совершенно прозрачно для программиста. Такая связка позволяет очень удобно управлять настройками сразу нескольких окружений (например, один сервер конфигурации может обслуживать и тестовые, и продакшн сервера, хотя это и нежелательно) или нескольких инстансов задеплоенного приложения. Такое решение изначально разрабатывалось под микросервисную архитектуру, поэтому такую связку имеет смысл поднимать, если у вас инстансов приложения больше одного, и деплой полностью автоматизирован.
А ещё Spring Cloud Config умеет шифровать конфиги. Такие конфиги можно (хотя и не рекомендуется) выкладывать в публичный репозиторий, а при деплое просто подкладывать ключ для расшифровки (вот его ни в коем случае светить не нужно).
Конечно, всё вышеописанное можно реализовать и без Spring, но Spring очень сильно всё облегчает.
Комментариев нет:
Отправить комментарий