12 Factor App Methodology
Introduction
In the past, developing software in a traditional environment meant long wait times for server assembly and tightly-coupled apps and server code. now Fast Forward to modern cloud provision, server scaling takes minutes. Heroku introduced the 12-factor app methodology for developing modern cloud applications. This methodology is crucial for building software-as-a-service applications due to its scalability and ease of deployment.
In the modern era, the software is commonly delivered as a service called: web apps or software as a service. It was created by developers at Heroku to help software engineers design apps optimized for deployment on cloud platforms.
Background
The twelve-factor app is a methodology for building software-as-a-service apps that:
Use declarative formats for setup automation, to minimize time and cost for new developers joining the project;
Have a clean contract with the underlying operating system, offering maximum portability between execution environments;
Are suitable for deployment on modern cloud platforms, obviating the need for servers and systems administration;
Minimize divergence between development and production, enabling continuous deployment for maximum agility;
And can scale up without significant changes to tooling, architecture, or development practices.
The twelve-factor methodology can be applied to apps written in any programming language, and which use any combination of backing services (database, queue, memory cache, etc).
The Twelve Factors
Codebase
One codebase, tracked in version control, many deploys
Maintain a single codebase for your app, typically in a version control system like Git. This codebase can be deployed to multiple environments, such as development, staging, and production.
for Microservice Architecture to maintain a single repo for each Microservice Architecture instead of storing all the services in a single repo
Dependencies:
Explicitly declare and isolate dependencies
All external libraries and dependencies should be explicitly declared, typically in a dependency management file (like requirements.txt for Python, package.json for Node.js, go.mod for go, ).
Do not rely on system-wide packages. Install the project-wide package dependencies so that dependencies are isolated from project to project.
Config:
Store config in the environment
Store all configuration settings (such as database URIs, API keys and Secrets ) in environment variables. This ensures that settings can be changed without modifying the codebase, making it easier to deploy the app in different environments.
so that changing the environment variables will deploy the application in different stages
Backing Services:
Treat Resources as an cattle instead of pets:
External resources like databases, message queues, and caches should be treated as replaceable attached services. You should be able to swap them out without requiring code changes, as long as they follow the same interface.
If there are any errors in a resource, it should be removed and a new one created instead of troubleshooting the existing one
Build, Release, Run:
Strictly separate build and run stages
The app's lifecycle should be split into three stages:
Build: Converts the codebase into an executable.
Release: Combines the build with environment-specific configuration.
Run: Executes the app in its target environment (e.g., production).
Processes:
Execute the app as one or more stateless processes
- The app should be designed as stateless processes, where any persistent data (like user sessions) should be stored in external services (like databases or caches). This allows processes to be easily restarted or replicated.
Port Binding:
Export services via port binding
- The app should be self-contained and expose its functionality through ports. For example, a web app should include its own web server and bind to a port to receive HTTP requests.
Concurrency:
Scale out via the process model
- The app should be designed to scale horizontally by increasing the number of processes or instances, rather than scaling vertically (e.g., adding more CPU or RAM to a single instance).
Disposability:
Maximize robustness with fast startup and graceful shutdown
- Processes should be disposable, meaning they can be started or stopped quickly. This ensures that your app can be resilient to crashes and deploys new code without significant downtime.
Dev/Prod Parity:
Keep development, staging, and production as similar as possible:
- Minimize the differences between development, staging, and production environments to avoid bugs related to environment-specific behavior. For example, use the same database engine and cloud services in all environments.
Logs:
Treat logs as event streams:
- The app should not manage log files. Instead, logs should be treated as a continuous stream of events and sent to an external system for analysis and storage.
Admin Processes:
Run admin/management tasks as one-off processes:
- Administrative tasks (e.g., database migrations, data cleanup) should be run as one-off processes in the same environment as the app, but without altering the appโs code.
Benefits of 12 Factor App Methodology
Simplified deployment and infrastructure management.
Flexible scaling with a dyno-based architecture.
The Rich ecosystem of add-ons for extending functionality.
Security, monitoring, and logging are built-in.
A platform optimized for developer productivity and collaboration.
Conclusion
- By adhering to these 12 principles, you ensure that your application is modular, portable, and scalable, which is especially critical in cloud-based environments like Heroku, AWS, or other PaaS (Platform-as-a-Service) solutions.
References
Subscribe to my newsletter
Read articles from Dinesh T directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Dinesh T
Dinesh T
Passionate and committed DevOps Engineer with a solid grasp of computer science basics ๐ป, containerization ๐ณ, cloud tech โ๏ธ, micro-services architecture ๐๏ธ, and DevOps methodologies ๐. Proficient in enhancing and overseeing CI/CD pipelines ๐ and managing resilient cloud infrastructure ๐ for maximum availability. Iโm constantly broadening my expertise in DevOps, Cloud, and Technology ๐, and love sharing my insights with the community ๐ in a more captivating and concise way.