The Twelve-Factor App
The Twelve-Factor App is a methodology for building software-as-a-service (SaaS) applications. It was drafted by developers at Heroku to synthesize their experience with building and deploying hundreds of apps.
The 12 Factors
1. Codebase
One codebase tracked in revision control, many deploys. There is always a one-to-one correlation between the codebase and the app. If there are multiple codebases, itβs not an app β itβs a distributed system.
2. Dependencies
Explicitly declare and isolate dependencies.
Never rely on implicit existence of system-wide packages. Use a dependency declaration manifest (like package.json or requirements.txt) and a dependency isolation tool (like Docker or virtualenv).
3. Config
Store config in the environment. Configuration that varies between deployments (staging, production, developer environments) should be stored in environment variables, not in the code.
4. Backing Services
Treat backing services as attached resources. A backing service is any service the app consumes over the network (databases, messaging systems, SMTP services). The app should treat them as attached resources, accessed via a URL or other locator stored in the config.
5. Build, Release, Run
Strictly separate build and run stages.
- Build: Converts code repo into an executable bundle.
- Release: Combines the build with the deploy's config.
- Run: Runs the app in the execution environment. You cannot change code at runtime.
6. Processes
Execute the app as one or more stateless processes. Processes are stateless and share-nothing. Any data that needs to persist must be stored in a stateful backing service (database). Sticky sessions are a violation.
7. Port Binding
Export services via port binding. The app is self-contained and does not rely on runtime injection of a webserver into the execution environment to create a web-facing service. The web app exports HTTP as a service by binding to a port, and listening to requests coming in on that port.
8. Concurrency
Scale out via the process model. Scale by adding more processes (workers), not by making one process larger (threads/vertical scaling).
9. Disposability
Maximize robustness with fast startup and graceful shutdown. Processes should start quickly (for scaling) and shut down gracefully (finish current request, put jobs back on queue) when they receive a SIGTERM.
10. Dev/Prod Parity
Keep development, staging, and production as similar as possible. Minimize the time gap, personnel gap, and tools gap between development and production. Use the same backing services (e.g., don't use SQLite in dev and PostgreSQL in prod).
11. Logs
Treat logs as event streams.
The app should not concern itself with routing or storage of its output stream. It should write everything to stdout. The execution environment captures this stream and routes it to final destinations (Splunk, ELK).
12. Admin Processes
Run admin/management tasks as one-off processes. Admin tasks (database migrations, REPL shells) should run in an identical environment as the regular long-running processes of the app.
programming/microservices-architecture programming/cloud-computing-basics programming/devops programming/docker-and-containers