The Twelve-Factor App 
SaaS delivery that doesn't hurt (as much)  
This presentation
- Plant a seed  
- Get you excited 
- (hopefully) 
Three years ago
- one VPS (512M, combined app/db)  
- FTP-based deploy  
- coding in production  
- 
 coding in production
- 
 
Today
- upwards 30 VMs, load balancers and DB servers 
- several geographically distributed data centers 
- CDN delivery (Oct 2015: avg. 293 GB data over 31K requests per day) 
- SCM-based deploy and rollback 
The future
- One platform to rule them all 
- Automatic, data-driven scaling 
- Continuous delivery 
- Containerization 
- Resource management 
- Micro services 
We're building complex systems!
(and that's great, but...) 
The Twelve-Factor App
One app <=> one codebase
Explicit dependencies
Config by environment 
Backing services 
Build, release, run 
Stateless processes 
Self-contained services 
Scale via the process model 
Disposability
Dev-prod parity
Logs as streams
Admin processes 
One app <=> one codebase
- Codebase = repository 
- Use version control (duh!) 
- Shared code as dependencies  
- Same codebase across deploys 
Why? 
- Clean mapping between revision and deploy 
- Promotes explicit dependencies 
- Great for CI 
Explicit dependencies
- Dependency declaration (e.g. pom.xml, project.json)  
- Dependency resolution (e.g. Maven, KPM)  
- Dependency isolation (e.g. bundle exec) 
- No deps in version control, but commit "lock file" 
Why? 
- Facilitates dev-prod parity  
- Easier dev workflow  
Config by environment
- No config in version control  
- Use environment variable substitution  
- No "grouping"  
Why? 
- Agnostic  
- Simple to distribute  
- Secure  
Build, release, run
- Strict separation of stages  
- Build produces binaries  
- Release combines binaries and configuration  
- Run executes a given release  
- Releases are versioned  
- Configuration change = new version  
Why? 
- Run stage is kept as dumb as possible  
- Easier automation  
- Behaviour is versioned  
The shared state problem (2)
The shared state problem (3)
The shared state problem (4)
Stateless processes (cont.)
Why?
- Resilience  
- Scaling  
- Automation  
Self-contained services
- Bundle web server 
- Export port bindings 
web: bundle exec rails server -p $PORT
Why? 
- Web server becomes just another dependency 
- The Docker Way ™
Scale via the process model
- Process formation
- Scale individually
- Managed externally
web: bundle exec rails server -p $PORT
worker: bundle exec rake jobs:work
Disposability
- Assume processes may be started/stopped at any time  
- Minimize startup time  
- Shut down gracefully  
- POSIX signals (SIGTERM/SIGKILL) 
Why? 
- Elastic scaling  
- Rapid deployment  
Dev-prod parity
- Deploy often  
- Deploy yourself  
- Don't rely on abstractions 
Why? 
- Ensure well-behavior 
- Easier rollback 
- Devs know what they're doing 
Logs as streams
- Log files, no more!  
- Just print to STDOUT/STDERR  
Logs as streams (2)
- Log files, no more!
- Just print to STDOUT/STDERR
Why?
- Less management  
- Indexing and analysis  
- Storage allocation  
Admin processes
- Run admin/management tasks as one-off processes  
- ...inside the environment of the app  
- Database migrations  
- REPL  
- Admin code should ship with application code  
Why? 
- Ease of use  
- Reproducible environment  
 
    
The Twelve-Factor App 
SaaS delivery that doesn't hurt (as much)