Upgrade to Pro — share decks privately, control downloads, hide ads and more …

12 Factor App: Red Dot Ruby Conf

12 Factor App: Red Dot Ruby Conf

This is the talk I gave at Red Dot Ruby Conf. http://12factor.net

Db953d125f5cc49756edb6149f1b813e?s=128

Richard Schneeman

May 21, 2012
Tweet

Transcript

  1. May 18th 2012 Richard Schneeman @schneems the 12factor App Monday,

    May 21, 12
  2. Hello Monday, May 21, 12

  3. 㟬޷ Monday, May 21, 12

  4. It’s Friday Monday, May 21, 12

  5. 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
  6. 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
  7. Monday, May 21, 12

  8. 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
  9. Config Monday, May 21, 12

  10. Config • What varies between deploys • resource strings to

    databases • credentials to S3, twitter, facebook, etc. • canonical values, hostname • security tokens Monday, May 21, 12
  11. Config Does NOT go in source control Monday, May 21,

    12
  12. secrets in source control aren’t secret Monday, May 21, 12

  13. Open source- able? Monday, May 21, 12

  14. Rotateable Secure Keys Monday, May 21, 12

  15. Config: Development $ cat .env S3_KEY=FOONVBAR FACEBOOK_APP_ID=281502345249818 FACEBOOK_SECRET=d59c2a439f4be49cf1 Monday, May

    21, 12
  16. Config: Development $ foreman run rails console ruby-1.9.3 > puts

    ENV[“S3_KEY”] ruby-1.9.3 > “FOONVBAR” Monday, May 21, 12
  17. Config: Development $ foreman start $ cat Procfile web: bundle

    exec unicorn -p $PORT -c ./config/unicorn.rb worker: bundle exec rake jobs:work Monday, May 21, 12
  18. Config: Production • Heroku ‘config’ • Read from environment $

    heroku config:add S3_KEY=FOONVBAR > puts ENV[‘S3_KEY’] > “FOONVBAR” Monday, May 21, 12
  19. 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
  20. development vs. production Monday, May 21, 12

  21. 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
  22. Development • Real/consistent data $ heroku db:pull Monday, May 21,

    12
  23. Development • Real/consistent data $ rake users:drop $ rake users:create

    # ... $ rake master:create Monday, May 21, 12
  24. Bundler • Bundle versions specified • ~> • Use semantic

    versioning • Prevent unexpected library changes gem 'twitter', '~> 2.0.2' gem "koala", '~> 1.2.1' gem 'tumblr-api', '~> 0.1.4' # ... Gemfile Monday, May 21, 12
  25. 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
  26. but... it worked in development Monday, May 21, 12

  27. Staging • A “production like” environment • Try stuff out

    here before production Monday, May 21, 12
  28. Staging [remote "production"] url = git@heroku.com:hourschool.git fetch = +refs/heads/*:refs/remotes/heroku/* [remote

    "staging"] url = git@heroku.com:hourschool-drama.git fetch = +refs/heads/*:refs/remotes/heroku/* .git/config Monday, May 21, 12
  29. Staging $ git push --remote staging $ cap deploy staging

    Monday, May 21, 12
  30. Stage with Data Production Development Staging Monday, May 21, 12

  31. Multiple Staging [remote "production"] # ... [remote "staging"] # ...

    [remote "staging-bill"] # ... [remote "staging-ted"] # ... .git/config Monday, May 21, 12
  32. 1 app 1 codebase Monday, May 21, 12

  33. 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
  34. 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
  35. 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
  36. logging Monday, May 21, 12

  37. 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
  38. Logging • Record Logs & Errors • New Relic (rpm)

    • Scout • Loggly • Papertrails • Airbrake (hoptoad) Monday, May 21, 12
  39. Logging • Help when the problem is intermittent • Too

    much traffic for tail to be effective • Provide additional insights Monday, May 21, 12
  40. 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
  41. 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
  42. scale out Monday, May 21, 12

  43. Web Instances • Handle web requests • More instances =

    more throughput • Worker instances can help offload tasks Monday, May 21, 12
  44. 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
  45. 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
  46. the web app demystified Monday, May 21, 12

  47. Twelve Factor Monday, May 21, 12

  48. 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
  49. 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
  50. Questions? @schneems Monday, May 21, 12

  51. 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
  52. 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
  53. 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