сеньорчикОткрыть в Telegram
← вся теориятеория к собесу · Docker и Kubernetes

Инфраструктура сервиса: конфиг и 12-factor

Конфигурация по 12-factor

12-factor - свод правил, по которым приложение живёт в облаке, и его любимая на собесе часть - конфигурация: что различается между средами, должно быть снаружи кода. Проверяют, понимаешь ли ты, почему один образ едет во все среды и почему секретам не место в git.

Типовые формулировки: «где хранить конфиг для разных сред?», «почему один образ на все среды?», «куда девать секреты».

Конфиг среды - в переменных окружения

Принцип 12-factor: всё, что РАЗЛИЧАЕТСЯ между средами - адреса БД, ключи, флаги - живёт в переменных окружения, а не в коде и не в VCS (version control system). Это отделяет код от среды: сам код одинаков, различия задаются снаружи.

Отсюда единый артефакт: один протестированный образ едет во все среды, а различия подставляются переменными при запуске. Прод гоняет РОВНО то, что проверено в CI, не пересобранное под прод, а тот же самый образ. Хардкодить конфиг в коде или заводить git-ветку под каждую среду - прямое нарушение: код начинает различаться там, где различаться должна только конфигурация.

// Собирать отдельный образ под прод - подрывать доверие к тому, что тестировалось: в прод уезжает не проверенный артефакт, а его двойник.

12-factor
конфиг среды в переменных окружения, отдельно от кода
единый артефакт
один образ на все среды, различие - конфиг

Секреты - вне кода и образа

Секреты - пароли, ключи, токены - не хранят в git и не зашивают в образ. Причина та же, что у конфига, но острее: образ один на все среды и легко утекает, а git хранит историю навечно - закоммиченный однажды секрет остаётся в истории, даже если удалить его следующим коммитом.

Правильно - переменные окружения при запуске или секрет-менеджер (Vault, облачные secrets). Тогда секрет не является частью артефакта и его можно ротировать, не пересобирая образ.

// Практическое следствие: .env с реальными секретами в .gitignore, а в репозитории - только .env.example с именами переменных без значений.

секреты
пароли/ключи вне кода и образа

Как отвечать: «Почему один и тот же образ должен ехать во все среды?»

Чтобы в прод попадало ровно то, что проверено. По 12-factor различаться между средами должна только конфигурация - адреса БД, ключи, флаги, и она задаётся переменными окружения при запуске, а не пересборкой. Тогда артефакт неизменен: образ, прошедший тесты в CI, тот же самый едет в stage и prod, отличаясь лишь подставленным окружением. Если же собирать отдельный образ под прод, я в прод выкатываю не тот бинарник, что тестировал, а его двойника, и доверие к тестам падает, потому что различия сборки могут принести баг, которого в CI не было. Секреты по той же логике держу снаружи - в переменных или секрет-менеджере, не в образе и не в git.

Названа суть (в прод едет проверенный артефакт), объяснено почему отдельная сборка под прод опасна и связано с конфигом и секретами - системное понимание, а не пересказ правила.

На чём валят

  • Хардкодить конфиг среды в коде или заводить ветку git на каждую среду.
  • Собирать отдельный образ под прод - подрывает доверие к тому, что тестировалось.
  • Хранить секреты в git или зашивать их в образ - утекут и останутся в истории навсегда.
  • Класть реальный .env в репозиторий вместо .env.example с одними именами переменных.

Проверьте себя

Пять вопросов из банка по этой подтеме. Всего их 12, остальные разбираются в тренажёре.

  1. #config_12factor1 / 5
    Один и тот же образ едет на dev и prod. Как получить разное поведение сред?
    A)Держать if-ветки в коде, проверяющие имя хоста текущей машины
    B)Пересобирать образ на каждый деплой с новыми значениями внутри
    C)Прокинуть разные переменные окружения при запуске образа
    D)Собрать два отдельных образа с зашитыми внутрь настройками каждой среды
    показать ответ и разбор
    +C)Прокинуть разные переменные окружения при запуске образа

    // разбор: Ключевой смысл вынесенного конфига: один протестированный образ — во все среды, а различия (адрес БД, уровень логов, флаги) задаются переменными окружения при запуске. Тогда prod гоняет ровно то, что проверено в CI, а не пересобранный заново артефакт. Разные образы под среды сводят на нет гарантии тестирования.

  2. #config_12factor2 / 5
    Где по 12-factor держат конфиг, различающийся между средами (адреса БД, ключи)?
    A)В отдельной ветке git на каждую среду, где значения прописаны прямо в файлах
    B)В самом коде приложения, чтобы он деплоился вместе с нужными значениями
    C)В переменных окружения, отдельно от кода и вне системы контроля версий
    D)В образе Docker, зашитым на этапе сборки под каждую конкретную среду отдельно
    показать ответ и разбор
    +C)В переменных окружения, отдельно от кода и вне системы контроля версий

    // разбор: 12-factor предписывает хранить конфиг, различающийся между средами (адреса сервисов, учётные данные, флаги), в переменных окружения — отдельно от кода и вне VCS. Это отделяет код от среды: один и тот же образ/кодовая база работает всюду, а различия задаются переменными при запуске. Хардкод в коде или ветка git на каждую среду ломают этот принцип.

  3. #config_12factor3 / 5
    Один протестированный образ едет во все среды, различия — переменными. Что это даёт?
    A)Ускоряет сборку за счёт того, что образ собирается заново под каждую среду отдельно
    B)Позволяет для прода собирать отдельный, специально оптимизированный под него образ
    C)Даёт возможность менять код приложения прямо в проде без пересборки образа
    D)Прод гоняет ровно то, что проверено в CI — исчезает «в тесте работало»
    показать ответ и разбор
    +D)Прод гоняет ровно то, что проверено в CI — исчезает «в тесте работало»

    // разбор: Единый артефакт — тот же образ проходит CI и едет в staging и прод без пересборки, а среды различаются лишь переменными окружения. Так на проде исполняется ровно то, что протестировано, — исчезает класс проблем «в тесте работало, на проде нет» из-за разных сборок. Собирать отдельный образ под прод — значит запускать непроверенное и подрывать доверие к тестам.

  4. #config_12factor4 / 5
    Почему 12-factor требует, чтобы процессы приложения были stateless?
    A)Любой инстанс обслужит любой запрос, легко масштабировать и перезапускать
    B)Чтобы каждый процесс намертво привязать к конкретному пользователю на всё время сессии
    C)Чтобы ускорить обработку запросов за счёт полного отказа от обращений к базе данных
    D)Чтобы приложение вообще не хранило никаких данных, включая базу данных и файлы
    показать ответ и разбор
    +A)Любой инстанс обслужит любой запрос, легко масштабировать и перезапускать

    // разбор: Stateless-процессы не хранят состояние между запросами в своей памяти/на своём диске: сессии, кеши, данные выносят во внешние backing-сервисы (БД, Redis). Тогда любой инстанс обслужит любой запрос, их можно свободно добавлять, убирать и перезапускать (в том числе при деплое и падениях) без потери состояния. Липкое состояние в процессе ломает горизонтальное масштабирование и устойчивость.

  5. #config_12factor5 / 5
    12-factor трактует БД, кеш, брокер как «attached resources». Что это меняет?
    A)Их подключают по конфигу-URL и меняют без правки кода — как сменные ресурсы
    B)Запрещает использовать управляемые облачные базы данных и кеши в приложении
    C)Требует, чтобы все они физически работали на той же машине, что и приложение
    D)Означает, что менять адрес или экземпляр ресурса можно только пересборкой кода
    показать ответ и разбор
    +A)Их подключают по конфигу-URL и меняют без правки кода — как сменные ресурсы

    // разбор: Backing-сервисы (БД, кеш, очередь, SMTP) 12-factor рассматривает как подключаемые ресурсы, адресуемые через конфиг (обычно URL в переменной окружения). Локальный Postgres и managed-облачный — для кода одно и то же: сменить один на другой можно правкой конфига, без изменения кода. Это развязывает приложение и конкретные экземпляры ресурсов, упрощая переезды, замену и работу в разных средах.

дальше

Теорию прочитали. Навык ставится повторением

В Сеньорчике эта подтема идёт в ежедневных сессиях: движок возвращает её, пока ответы не станут уверенными, и ведёт прогресс отдельно по каждой подтеме. Теория внутри тоже бесплатна, лимит только на количество вопросов в день.