The Twelve Factors
I. Codebase
One codebase per app and its many deploys (running instances).
Versioned (repo); Dev, Test, Staging, Prod, ... all share a root commit.
II. Dependencies
Explicitly declare and isolate dependencies per dependency declaration manifest;
dependencies scoped per app (vendoring/bundling), not system-wide pkgs.
Any required system (bash
) tools (e.g., curl
) are vendored into the app.
III. Config
Store (per deploy) configuration @ Env. Vars. (env
);
mutually orthogonal, language/OS agnostic.
IV. Backing services
Loose coupling; treat backing services as attached resources;
swappable sans app code change, only config change;
accessed per URL or other locator/credentials stored in the config;
app makes no distinction between local and third party services
V. Stages: Build, Release, Run
Strict separation between build and release stages.
- Build: transforms code repo into an executable bundle; a build.
- Release:
ID = Build + Config
; immutable
executable @ execution environment - Run (runtime): runs app @ execution environment; leanest stage;
runs specified app process(es) against a selected app release.
VI. Processes
Execute the app as one or more stateless processes;
each process is stateless and shares nothing.
Stateful backing service(es) handle persistence.
Process may utilize single-transaction cache.
No sticky sessions; use time-expiration datastore (Memcached/Redis).
Package assets during the build stage.
VII. Port binding
Export services via port binding
App is completely self-contained; no runtime injection of a webserver;
exports HTTP as a service by binding to a port,
and listening to requests coming in on that port;
one app can become the backing service for another app,
whereof the backing app URL is declared in the config of consuming app.
VIII. Concurrency
Scale out via the Unix process model (service daemons)
The share-nothing, horizontally partitionable nature of twelve-factor app processes
means that adding more concurrency is a simple and reliable operation.
IX. Disposability
Maximize robustness with fast startup and graceful shutdown;
easier to move processes to new physical machines when warranted.
Processes shut down gracefully when they receive a SIGTERM signal from the process manager.
Processes should also be robust against sudden death, in the case of a failure in the underlying hardware.
A recommended approach is use of a robust queueing backend;
return jobs to the queue when clients disconnect or time out.
X. Dev/Prod Parity
Keep development, staging, and production as similar as possible.
Design for Continuous Deployment.
XI. Logs
Treat logs as event streams
Logs provide visibility into the behavior of a running app; the stream of aggregated,
time-ordered events collected from the output streams of all running processes and backing services;
flow continuously as long as the app is operating.
Each running process writes its event stream, unbuffered, to stdout.
@ development, can observe the app’s behavior.
@ staging or production deploys, each process’ stream is managed by the execution environment.
Open-source log routers (Logplex/Fluentd) are available for this purpose.
The event stream for an app can be routed to a file, or watched via realtime tail in a terminal.
The stream can be sent to a log indexing and analysis system (Splunk), or warehoused (Hadoop/Hive).
Allows for powerful/flexible introspecting an app’s behavior:
XII. Admin processes
Run admin/management tasks as one-off processes
Languages which provide a REPL shell out of the box make this easy.