February 22, 2012 - 12 Factor App

Where we’ve been

  • Version control

    • folders
    • cvs/svn
    • git/mercurial
  • Dependency Management

    • python setup.py install
    • easy_install somepackage
  • Deployment

    • rsync myproject runserver
    • scp

Where we’re going

  • Modern Version Control makes it possible to:

    • 1 code base with many deploys
  • Dependency Management

    • pip install somepackage
    • pip freeze > requirements.txt
  • Deployment

    • Capistrano
    • Tarball
    • slug
    • Bundle everything together so rollbacks are trivial

What is 12 Factor?

A set of practices used by Heroku that serves as a mantra as to what they are doing.

  • Declarative Setup - Minimize setup time
  • Clean contracts - Portability to run anywhere
  • Deploy practices - Cloud and horizontal scaling
  • Minimize Divergence - Continuous Deployment

Dev/Prod Parity

  • Dev = Staging = Prod
  • sqlite != postgres = postgres


Don’t use sqlite in dev or you get screwed! This happened to me!


Don’t do this:

$ ls

This is fail:

# settings.py
from local_settings import *

Or this:

# settings/prod.py
from base import *

Do this instead:

# settings.py
MY_SETTING = os.environ.get("MY_SETTING")


  • Don’t worry about languages/frameworks being able to scale.
  • Better to let the server side handle it.
  • Use worker processes


We use logs thus:

$ tail -f access_log

How we percieve logs:

$ ls

But when it comes down to it, logs are really an event stream!

  • Imagine if logs were aggregated into one stream
  • Then you can filter out the parts you want
  • Order things the way you want

Future Thoughts

  • pip should be able to specify the version of Python
  • environment settings should be set as environment variables rather than specified in Python code. Makes local setup and deployment much easier. From experience this is very true.