How to Achieve 12-Factor App “Config” Glory with Django Settings Files
A while back we read the 12-factor app and fell in love with methodology. While we were already practicing most of the steps we fell short in the application’s settings file department. Everything was hard coded in the file and we used a base.py, local.py, staging.py, production.py and local.py.tmpl files to sort everything out between different developers workstations and our production environment. After the following method we only have one file.
There were three major problems with this model.
- We couldn’t track of new settings. Every time a sprint story introduced a new app to the mix that had a new setting we found that we would close a story without updating the template files. This happens especially if the app requires some sort of API key.
- Its harder to bring on new developers because you don’t trust them with your keys and passwords. With this model, they have to setup their own keys. The company’s keys are only known by administrators or the people that absolutely need to know them.
- We were committing keys to the repos!! This is probably the biggest problem we were facing. We use Bitbucket and Mecurial and although their track record is a little better than their competitor in regards to security notices we don’t want to trust them with our Amazon or Stripe keys.
So what do you need to get started? The list is small.
- You need to use virtualenv locally and on production unless you are using a cool PaaS like AWS Elastic Beanstalk, Heroku, or Openshift where your set environment variables on deployment. C'mon, if you are not already using virtualenv what the heck are your doing with your life?!? All of the Platform as a Service (PaaS) solutions I named have a way for you to set environment variables during deployment. Whether its a separate configuration file or deployment hooks doesn’t really matter.
- Add the unipath library to your life. Unipath is package for doing pathname calculations and filesystem access in an object-oriented manner, an alternative to os.path.*, shutil.*, glob, and some os.* functions (yep I stole that directly from pypi). Trust me life is a lot easier with unipath.
So enough of your stupid blog post show me the sample code already!!! Here you go.