May 18th
2012
Richard Schneeman
@schneems
the
12factor
App
Monday, May 21, 12
Slide 2
Slide 2 text
Hello
Monday, May 21, 12
Slide 3
Slide 3 text
㟬
Monday, May 21, 12
Slide 4
Slide 4 text
It’s
Friday
Monday, May 21, 12
Slide 5
Slide 5 text
whoami
• @Schneems
• BSME with Honors from Georgia Tech
• 5 + years experience Ruby & Rails
• Work for @Heroku
• Rails 3.1, 3.2, & 4.0 contributor
• 3 + years technical teaching
• UT Austin
Monday, May 21, 12
Slide 6
Slide 6 text
Twelve Factor
• Can apply to any language
• Speeds up deployment, makes scaling
easier & keeps apps clean
• Developed over direct exposure to the
deployment of hundreds of thousands of
apps
Monday, May 21, 12
Slide 7
Slide 7 text
Monday, May 21, 12
Slide 8
Slide 8 text
Code + Methodology
• Speed and confidence through:
• Development environment
• Staging environments
• Consistent codebase practices
• Quick access to logs and metrics
• Easy scaling architecture
Lets take a look
Monday, May 21, 12
Slide 9
Slide 9 text
Config
Monday, May 21, 12
Slide 10
Slide 10 text
Config
• What varies between deploys
• resource strings to databases
• credentials to S3, twitter, facebook, etc.
• canonical values, hostname
• security tokens
Monday, May 21, 12
Slide 11
Slide 11 text
Config Does NOT
go in
source control
Monday, May 21, 12
Slide 12
Slide 12 text
secrets in
source
control
aren’t
secret
Monday, May 21, 12
Slide 13
Slide 13 text
Open
source-
able?
Monday, May 21, 12
Slide 14
Slide 14 text
Rotateable
Secure
Keys
Monday, May 21, 12
Slide 15
Slide 15 text
Config: Development
$ cat .env
S3_KEY=FOONVBAR
FACEBOOK_APP_ID=281502345249818
FACEBOOK_SECRET=d59c2a439f4be49cf1
Monday, May 21, 12
Slide 16
Slide 16 text
Config: Development
$ foreman run rails console
ruby-1.9.3 > puts ENV[“S3_KEY”]
ruby-1.9.3 > “FOONVBAR”
Monday, May 21, 12
Config: Production
• Heroku ‘config’
• Read from environment
$ heroku config:add S3_KEY=FOONVBAR
> puts ENV[‘S3_KEY’]
> “FOONVBAR”
Monday, May 21, 12
Slide 19
Slide 19 text
Config: Production
• On A VPS
• Use Foreman
• Add values directly to command
$ S3_KEY=FOONVBAR rails console
ruby-1.9.3 > puts ENV[‘S3_KEY’]
ruby-1.9.3 > “FOONVBAR”
Monday, May 21, 12
Slide 20
Slide 20 text
development
vs.
production
Monday, May 21, 12
Slide 21
Slide 21 text
Development
• As close to production as possible
• Same data-stores (postgres, memcache)
• Same language versions (Ruby 1.9)
• Real/consistent data
Monday, May 21, 12
Slide 22
Slide 22 text
Development
• Real/consistent data
$ heroku db:pull
Monday, May 21, 12
Slide 23
Slide 23 text
Development
• Real/consistent data
$ rake users:drop
$ rake users:create
# ...
$ rake master:create
Monday, May 21, 12
README.md
• Living document
• Standardize dev environment
• Instructions for external dependencies
• Instructions for starting processes
• Problem with dev environment?
• Put the fix in the readme
$ brew install memcache
$ foreman start
Monday, May 21, 12
Slide 26
Slide 26 text
but... it
worked in
development
Monday, May 21, 12
Slide 27
Slide 27 text
Staging
• A “production like” environment
• Try stuff out here before production
Monday, May 21, 12
Git
• All code for the app goes in one repository
• Split out easily reusable code into separate
libraries
• i.e. github.com/schneems/wicked
Monday, May 21, 12
Slide 34
Slide 34 text
Git Flow
• New feature?
• Put it in a branch
• Refactoring code?
• Put it in a branch
• Need a New Demo?
• Put it in a branch
Monday, May 21, 12
Slide 35
Slide 35 text
Branches
• Keep the codebase clean
• Testing feature branches in staging
$ git co -B schneems/solr_search
$ git push --remote staging
schneems/solr_search:master
Monday, May 21, 12
Slide 36
Slide 36 text
logging
Monday, May 21, 12
Slide 37
Slide 37 text
Logging
• Production errors still happen
• Tail logs to find the cause
• Use a logging service to dig in deeper
$ heroku logs --remote production
--tail
Monday, May 21, 12
Slide 38
Slide 38 text
Logging
• Record Logs & Errors
• New Relic (rpm)
• Scout
• Loggly
• Papertrails
• Airbrake (hoptoad)
Monday, May 21, 12
Slide 39
Slide 39 text
Logging
• Help when the problem is intermittent
• Too much traffic for tail to be effective
• Provide additional insights
Monday, May 21, 12
Slide 40
Slide 40 text
Error Pages
• Admins get error
+ Backtrace
Couldn't find Course with ID=chunkybacon
Details
Params: {"action"=>"show", "controller"=>"courses", "id"=>"chunkybacon"}
Backtrace:
lib/active_record/relation/finder_methods.rb:304:in `find_one'
Monday, May 21, 12
Slide 41
Slide 41 text
Custom Error Pages
• Admins get error
+ Backtrace
Couldn't find Course with ID=chunkybacon
Details
Params: {"action"=>"show", "controller"=>"courses", "id"=>"chunkybacon"}
Backtrace:
lib/active_record/relation/finder_methods.rb:304:in `find_one'
Monday, May 21, 12
Slide 42
Slide 42 text
scale out
Monday, May 21, 12
Slide 43
Slide 43 text
Web Instances
• Handle web requests
• More instances = more throughput
• Worker instances can help offload tasks
Monday, May 21, 12
Slide 44
Slide 44 text
Workers
• Push long tasks that don’t fit in request
cycle to a worker
• Workers have the same code, but don’t
serve web content
• Perfect for
• Delayed emails
• Image Processing
• etc.
Monday, May 21, 12
Slide 45
Slide 45 text
Workers
• Use with a queuing system
• Resque (redis)
• DelayedJob (sql)
• Sidekiq
• Enqueue from the web server
• User signs up, queue email
• Dequeue & run on the worker
• Process next item in queue
Monday, May 21, 12
Slide 46
Slide 46 text
the web
app
demystified
Monday, May 21, 12
Slide 47
Slide 47 text
Twelve
Factor
Monday, May 21, 12
Slide 48
Slide 48 text
Twelve Factor
• Web apps have a contract with their
platform
• When the right development methods are
used, their app can be cleanly deployed
quickly
Monday, May 21, 12
Slide 49
Slide 49 text
Do You Like?
• Minimizing new developer overhead?
• Running in multiple environments?
• Easily scaling without tooling, architecture
or development headaches?
• Having the latest updates available to
users at a moments notice?
Read more at 12factor.net
Monday, May 21, 12
Slide 50
Slide 50 text
Questions?
@schneems
Monday, May 21, 12
Slide 51
Slide 51 text
12factor.net
• Codebase
• One codebase tracked in revision control, many deploys
• Dependencies
• Explicitly declare and isolate dependencies
• Config
• Store config in the environment
• Backing Services
• Treat backing services as attached resources
Monday, May 21, 12
Slide 52
Slide 52 text
12factor.net
• Build, Release, Run
• Strictly separate build and run stages
• Process
• Execute the app as one or more stateless processes
• Port Binding
• Export services via port binding
• Concurrency
• Scale out via the process model
Monday, May 21, 12
Slide 53
Slide 53 text
12factor.net
• Disposability
• Maximize robustness with fast startup and graceful shutdown
• Dev/Prod Parity
• Keep development, staging, and production as similar as possible
• Logs
• Treat logs as event streams
• Admin Process
• Run admin/management tasks as one-off processes
Monday, May 21, 12