Twelve-Factor App Principles
About
The Twelve-Factor App methodology is a set of best practices for building modern, scalable, and maintainable software-as-a-service (SaaS) applications. These principles are especially useful in cloud-native and microservices architectures and align well with Spring Boot microservices. Below is a detailed explanation of each factor and how it applies to Spring Boot microservices.
1. Codebase
One codebase tracked in version control, many deploys.
A Spring Boot microservice should have one codebase per service, stored in version control (e.g., Git).
Different environments (dev, QA, prod) should be different deployments of the same codebase, not separate branches or repositories.
2. Dependencies
Explicitly declare and isolate dependencies.
Spring Boot uses Maven or Gradle to manage dependencies via the
pom.xml
orbuild.gradle
.All dependencies should be declared explicitly, no reliance on global or system-wide packages.
3. Config
Store config in the environment.
Configurations like DB credentials, API keys, etc. should be stored in environment variables.
In Spring Boot:
Use
@Value
or@ConfigurationProperties
to inject values.Use profiles (
application-dev.yml
,application-prod.yml
) to manage environment-specific configurations.Externalize configuration via environment variables or tools like Spring Cloud Config.
4. Backing Services
Treat backing services as attached resources.
Databases, caches, message brokers, and other services should be treated as external resources.
In Spring Boot:
Use
application.yml
to define connections.Services can be swapped without code changes (e.g., switching from MySQL to PostgreSQL).
5. Build, Release, Run
Strictly separate build and run stages.
Spring Boot apps should follow these stages:
Build: Compile code and package it (
mvn package
).Release: Combine build with config (Dockerize to create Image or prepare deployment).
Run: Execute the app in a runtime environment using the release artifact.
6. Processes
Execute the app as one or more stateless processes.
Spring Boot microservices should be stateless – store no session or local data.
Any state should be stored in a database, cache, or distributed store.
This enables horizontal scaling (multiple instances).
7. Port Binding
Export services via port binding.
Spring Boot apps should be self-contained and expose HTTP endpoints via a port (
server.port
).No need for an external web server like Apache – use embedded servers (Tomcat, Jetty, etc.).
8. Concurrency
Scale out via the process model.
Multiple instances of the Spring Boot app should be run to scale.
Use orchestration tools (Docker, Kubernetes) to run multiple containers/pods.
Avoid thread-heavy logic unless necessary – prefer stateless RESTful design.
9. Disposability
Maximize robustness with fast startup and graceful shutdown.
Spring Boot apps should:
Start quickly (limit init logic).
Handle
SIGTERM
orSIGINT
for graceful shutdown (use@PreDestroy
orDisposableBean
).Clean up resources like DB connections on shutdown.
10. Dev/Prod Parity
Keep development, staging, and production as similar as possible.
Ensure environments are consistent:
Use Docker to simulate production locally.
Use similar databases and queues in all stages.
11. Logs
Treat logs as event streams.
Spring Boot should log to stdout/stderr using SLF4J/Logback.
Logs should not be written to files manually.
External tools like ELK Stack (Elasticsearch, Logstash, Kibana), or Splunk can collect logs.
12. Admin Processes
Run admin/management tasks as one-off processes.
Tasks like DB migration, data import/export should be run separately.
Use Spring Boot command-line runners (
CommandLineRunner
,ApplicationRunner
) or Flyway/Liquibase for DB migrations.
Last updated