The Twelve-Factor App methodology outlines best practices for building software-as-a-service apps. It recommends (1) storing code in version control, deploying the same code across environments, and avoiding multiple codebases; (2) explicitly declaring and isolating dependencies; and (3) storing configs in environment variables to separate config from code.
2. I. CODEBASE
• Use version control system
• Deploy every environments with same codebase
• In case of having multiple apps are sharing the same codebase
then consider to make it as shared library and use dependency
manager
• Performance issue is also one reason that cause you having
multiple codebase for an app. Please consider it as technical debt
to be pay off later.
3. II. DEPENDENCIES
• Full explicit dependencies declaration
• Deploy the same dependencies on every
environments
• Isolate dependencies from each environment
4. III. CONFIG
• Store configs in its own environment and use env variables
• Strict separation config from code
• Don’t check configs into code repository to prevent it scatter
around and be changed by anyone who can access repository.
• Try not to put environment name in configs. It does not scale
very well when you have many environments. It would cause
constantly updating those names all the time.
5. IV. BACKING SERVICES
• Treat backing services such as cache, database,
messaging queue or even api endpoint as
attached resources which you can change or
replace by configs without changing code.
6. V. BUILD, RELEASE, RUN
• Strict separate build, release and run
• Build stage is a precess to package or bundle codebase and dependencies
make it ready for Release stage.
• Release stage will combine the output from build stage and config for
deployed environment, tagging version and prepare roll-back releases.This
stage will not allow changing codebase or config, Just create new release if
needed.
• Run stage will run the output from release stage on the deployed
environment.
7. VI. PROCESSES
• Execute an app as stateless processes
• Persist data in backing service(datastore)
• No shared assets between processes, for example
any compiled assets for optimization etc.
• No session data saved in local disk or local memory
8. VII. PORT BINDING
• Export services via port binding.
• It simply says any services will communicate via url
to make it easy to change by configuration
settings.
9. VIII. CONCURRENCY
• Scale out via process model
• Support horizontal scaling
• App processes should not demonize or write PID
files, instead rely on system process manager like
“Systemd” to manage output stream, crashed
management.
10. IX. DISPOSABILITY
• App process can be started or stoped at any time to facilitate
scaling and rapid deployment.
• Minimize start up time
• Process should shut down gracefully when receive
SIGTERM(the signal from process manager). In term of Http, it
should terminate existing requests and deny incoming requests.
In term of long running process like worker, it should return
un-success tasks back to queue and stop pulling more task.
11. X. DEV/PROD PARITY
• Keep development/staging/production as similar as
possible
• Embrace continuous integration and delivery by
reduce the gaps of developer and deployer, time
and technologies stack.
12. XI. LOGS
• Treat logs as event stream
• App never concerns itself with logging stuff, Let the execution
environment to handle routing errors to destination storage
• Log should be time ordered
• Alert when the error exceed the threshold
• Graphing to see error trends
13. XII.ADMIN PROCESSES
• Provide one-off administrative console to allow
executing migration script or any one-time script
command
• It should be accomplished by the same
environment as production.
• Don’t run on local terminal or database directly.