Что такое методология Twelve-Factor App?

Ответ

Twelve-Factor App — это набор принципов для построения современных, масштабируемых и переносимых SaaS-приложений. Эти принципы помогают создавать приложения, которые легко развертывать, масштабировать и поддерживать в облачных средах.

Ключевые принципы:

  1. Одна кодовая база, отслеживаемая в системе контроля версий, — множество развертываний. Один репозиторий для приложения, но разные среды (разработка, staging, production).
  2. Явное объявление и изоляция зависимостей. Все зависимости должны быть явно объявлены (например, в package.json, requirements.txt, pom.xml) и никогда не подразумеваться.
  3. Хранение конфигурации в среде выполнения. Конфигурация (ключи API, строки подключения к БД) должна храниться в переменных окружения, а не в коде.
  4. Сопоставление сторонних сервисов с ресурсами. Базы данных, очереди сообщений, кэш должны рассматриваться как присоединяемые ресурсы, настраиваемые через конфигурацию.
  5. Строгое разделение стадий сборки и выполнения. Стадия сборки преобразует код в исполняемый артефакт. Стадия выполнения запускает этот артефакт. Их нельзя смешивать.
  6. Запуск приложения как одного или нескольких несостоятельных процессов. Приложение выполняется как один или несколько процессов, не хранящих состояние внутри себя. Состояние сохраняется во внешних хранилищах (БД, кэш).
  7. Экспорт сервисов через привязку портов. Приложение должно быть самодостаточным и предоставлять свои сервисы через объявленный порт.
  8. Масштабирование через модель процессов. Масштабирование осуществляется путем запуска большего количества идентичных процессов (горизонтальное масштабирование).
  9. Быстрый запуск и корректное завершение для обеспечения надежности. Процессы должны быстро запускаться и корректно завершаться при получении сигнала (например, SIGTERM), обеспечивая устойчивость к сбоям.
  10. Максимальное сближение сред разработки, промежуточной и рабочей. Следует минимизировать различия между средами, чтобы избежать проблем типа "работает на моей машине".
  11. Журналирование как поток событий. Приложение должно выводить журналы (логи) как поток событий в stdout. Агрегация и хранение логов — задача инфраструктуры.
  12. Задачи администрирования запускать как разовые процессы. Задачи по обслуживанию (миграции БД, запуск скриптов) должны выполняться в той же среде, что и основное приложение, но как разовые процессы.

Пример (Принцип 3 — Конфигурация):

# Плохо: конфигурация захардкожена
DATABASE_URL = 'postgresql://user:pass@localhost/db'

# Хорошо: конфигурация берется из переменных окружения
import os
DATABASE_URL = os.environ.get('DATABASE_URL')

Следование этим принципам упрощает CI/CD, развертывание в контейнерах (Docker) и оркестрацию (Kubernetes).

Ответ 18+ 🔞

А, блядь, Twelve-Factor App! Ну это ж классика, ёпта, как будто на дворе 2002-й год, а все до сих пор про неё говорят. Слушай, это типа такой свод правил, чтобы твоё приложение не было пиздопроебибным распиздяем, который работает только у тебя на ноуте, а в продакшене накрывается медным тазом. По сути, это инструкция, как не стать тем самым чуваком, которому доверия — ноль ебать.

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

Дальше — зависимости. Ёперный театр, сколько раз было: скачал проект, а он нихуя не запускается, потому что какому-то левому модулю нужна старая версия библиотеки, которая конфликтует со всей системой. Так вот, принцип говорит — явно объявляй все зависимости в специальном файле. package.json, requirements.txt — вот это всё. Чтобы любой идиот (или новый разработчик, что часто одно и то же) мог просто выполнить команду и получить рабочее окружение.

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

# Вот так делать — это манда с ушами. Удали это немедленно.
DATABASE_URL = 'postgresql://admin:qwerty123@prod-db.internal/super_secret_data'

# А вот так — уже похоже на человека разумного.
import os
DATABASE_URL = os.environ.get('DATABASE_URL')  # Берём из окружения, и никаких паролей в гите!

Пятый принцип — разделяй сборку и запуск. Сборка — это когда ты из своего кода делаешь готовый артефакт (пакет, контейнер). Запуск — это когда этот артефакт просто берут и запускают. Нельзя во время запуска лезть в интернет и доустанавливать пакеты — это волнение ебать для всей команды девопсов.

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

И самый, наверное, важный для понимания — одиннадцатый. Логирование. Приложение не должно само решать, куда писать логи — в файл server.log, в error.log, ещё куда-то. Оно должно просто вываливать поток событий в стандартный вывод (stdout). А дальше инфраструктура (Docker, Kubernetes, система логирования) сама разберётся, куда это всё складывать и как анализировать. Это гениально просто, потому что избавляет от тонн кастомного кода для ротации логов.

Если коротко, следовать этим принципам — это как не быть полупидором в разработке. Это делает приложение переносимым, его легко запустить в Docker-контейнере и оркестрировать через Kubernetes. Иначе будешь как тот самый Фарлаф, который только и думает, как бы объебать систему, а в итоге сам останешься с носом и с приложением, которое «работает только у меня».