Коротко: The Twelve-Factor App — 12 принципов приложений, которые легко разворачивать, масштабировать и сопровождать (особенно в облаке и контейнерах).

The Twelve-Factor App — это набор из 12 принципов построения приложений, которые легко разворачивать, масштабировать и сопровождать (особенно в облаке и контейнерах). Методология появилась в Heroku, но актуальна для любого современного бэкенда. Коротко пройдёмся по всем факторам с практическим смыслом.

1. Кодовая база (Codebase)

Одно приложение — один репозиторий, много развёртываний (dev, staging, prod) из одного кода. Не должно быть «прод-версии кода» отдельно от «дев-версии».

2. Зависимости (Dependencies)

Все зависимости объявлены явно (composer.json, go.mod) и изолированы. Приложение не полагается на «вдруг установленные» системные пакеты.

3. Конфигурация (Config)

Всё, что меняется между средами (пароли БД, ключи, URL), — в переменных окружения, а не в коде. Главный критерий: можно ли выложить код в открытый доступ без утечки секретов? Если нет — конфиг просочился в код.

DATABASE_URL=postgres://...
JWT_SECRET=...
MAILER_DSN=...

4. Сторонние сервисы (Backing services)

БД, очереди, кэш, почта — это подключаемые ресурсы, доступные по URL/конфигу. Локальную БД и облачную можно поменять местами, не трогая код, — только конфиг.

5. Сборка, релиз, запуск (Build, release, run)

Три строго разделённых стадии: build (собрали артефакт), release (артефакт + конфиг среды), run (запуск). Релизы неизменяемы и пронумерованы — можно откатиться на предыдущий.

6. Процессы (Processes)

Приложение — это один или несколько stateless процессов. Никакого состояния в памяти процесса между запросами: сессии, загрузки и кэш — во внешних хранилищах (Redis, БД, S3). Тогда процесс можно убить и поднять заново без потерь.

7. Привязка портов (Port binding)

Приложение само экспортирует HTTP, слушая порт, а не полагается на внешний веб-сервер для рантайма. Это делает его самодостаточным сервисом.

8. Параллелизм (Concurrency)

Масштабирование — горизонтальное, добавлением процессов разных типов (web, worker, scheduler), а не только наращиванием одного. Процессы дёшевы и независимы.

9. Утилизируемость (Disposability)

Процессы запускаются за секунды и аккуратно завершаются по SIGTERM (graceful shutdown: дообработать текущий запрос, вернуть задачу в очередь). Это позволяет быстро деплоить и переживать падения.

10. Паритет сред (Dev/prod parity)

Dev, staging и prod максимально похожи: те же версии БД, языка, сервисов. Docker и единые конфиги резко сокращают класс багов «у меня работает, на проде нет».

11. Логи (Logs)

Приложение пишет логи в stdout как поток событий и не заботится о файлах/ротации. Сбором, агрегацией и хранением занимается среда (journald, ELK, Loki).

12. Административные задачи (Admin processes)

Разовые задачи (миграции БД, скрипты обслуживания) запускаются в той же среде и из той же кодовой базы, что и приложение — например, php bin/console в том же контейнере.

Зачем это нужно

Следование 12 факторам делает приложение «облачно-дружелюбным»: его легко контейнеризировать, масштабировать горизонтально, разворачивать автоматически и откатывать. Даже если вы не в облаке — большинство принципов (конфиг в env, stateless-процессы, паритет сред, логи в stdout) делают эксплуатацию заметно спокойнее.

Не догма, а ориентир

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

Если приводите legacy-приложение к контейнерам и облачной эксплуатации и хотите выстроить это по уму — помогу на консультации или в рамках разработки.