Part 0 · 2 chapters · ~12 min

The Twelve-Factor Baseline and Its Limits

What twelve-factor got right about config in the environment, strict separation of config from code, why .env files leak, and the points where environment variables stop working: structure, change history, secrets, dynamic change and per-tenant variation.

1

Config in the environment, and where it breaks

The twelve-factor rule is store config in the environment, separate from code: the same build artifact runs in every environment, and nothing secret lives in the repository. It is still the right baseline.

where env vars stop workingsymptomnext step
structureJSON blobs in a variable, 80 variables per servicetyped config files plus a schema
change history"who changed RATE_LIMIT and when?"config in Git, or a config service with audit
secretsprinted in crash dumps, visible in /proc/<pid>/environ, copied into CI logs, sitting in .env files on laptopsa secrets manager, injected at runtime, short-lived
dynamic changea restart for every changeremote config or flags with safe reloads
per-tenant variationif statements per countrytenant config as data (Platform course)
code
// load and validate config once at startup: fail fast, with a clear message
import { z } from 'zod';
const Config = z.object({
  DATABASE_URL: z.string().url(),
  REDIS_URL: z.string().url(),
  TRANSFER_LIMIT_KOBO: z.coerce.number().int().positive().default(20_000_000),
  LOG_LEVEL: z.enum(['debug', 'info', 'warn', 'error']).default('info'),
});
export const config = Config.parse(process.env);     // throws at boot, not at 3 a.m. on first use
2

Configuration layers and precedence

Real services merge several layers. The bugs come from not knowing which layer set a value, and from layers that change without review.

CONFIGURATION LAYERS
later layers override earlier ones; know which layer a value came from
1. code defaultssafe values compiled in2. config filesconfig/production.yaml, per environment3. environment variablesset by the platform at deploy time4. remote configConsul, AppConfig, a config service, at runtime5. per-tenant / per-countryPlatform course P2: the country config6. feature flagsper user, per request
swipe the figure sideways, or tap expand for full screen
1/6
defaults
Every setting has a safe default in code, so a missing value never crashes the service or, worse, enables something dangerous.
safe defaults in codemissing config should be boring