12-Factor App & Config Management
Why config lives in env vars. Validating at startup. Feature flags done right.
The 12 Factor App
A methodology for building production-ready software-as-a-service apps:
- Codebase — One codebase per app, tracked in version control. Multiple deploys (prod, staging, dev).
- Dependencies — Explicitly declared, not assumed to be on the host (package.json, go.mod).
- Config — Store config in environment variables, not code.
- Backing Services — DB, Redis, queue treated as attached resources. Swap without code change.
- Build, Release, Run — Strictly separate build, release, and run stages.
- Processes — Stateless processes. Share nothing. State in backing services.
- Port Binding — Export services via port. App is self-contained.
- Concurrency — Scale out via the process model.
- Disposability — Fast startup, graceful shutdown. Robust against sudden death.
- Dev/Prod Parity — Keep dev, staging, prod as similar as possible.
- Logs — Treat logs as event streams. Never manage log files. Stdout only.
- Admin Processes — Run admin tasks as one-off processes (migrations, console).
Config Management
Rule: Never hardcode environment-specific values. Never commit secrets.
Environment variables are the 12-factor way:
DATABASE_URL=postgresql://user:pass@host:5432/db
REDIS_URL=redis://host:6379
JWT_SECRET=...
PORT=3000
In code, read from environment:
const dbUrl = process.env.DATABASE_URL;
if (!dbUrl) throw new Error("DATABASE_URL not set");
Validation at startup: if required config is missing, crash immediately with a clear error. Don't crash at 3 AM when that config is first used.
Config per environment: separate .env files for dev, docker-compose overrides for local, Kubernetes ConfigMaps + Secrets for prod. Never the same values across environments.
Feature flags: configuration controlling features (enable/disable). Can be environment variables, or a feature flag service (LaunchDarkly, Unleash) for dynamic runtime control.
The Backend from First Principles series is based on what I learnt from Sriniously's YouTube playlist — a thoughtful, framework-agnostic walk through backend engineering. If this material helped you, please go check the original out: youtube.com/@Sriniously. The notes here are my own restatement for revisiting later.