Private settings in Django and Deployment

I think a good example of how to do it is jcalazan/ansible-django-stack which besides the code includes a few links, in particular this one about How to deploy encrypted copies of your SSL keys and other files with Ansible and OpenSSL.


The answer is: http://12factor.net/config.

You should manage code-related differences between environments via different settings modules. An example of this would be adding debug_toolbar to INSTALLED_APPS locally, while removing it in production. To handle this aspect, rather than using the old try: import except ImportError: ... idiom and keeping an out-of-version-control local_settings.py on your local machine, you should instead keep all of your settings modules in version control, including your local settings. Then, in wsgi.py and manage.py, use os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myproject.conf.local') to default your project to use local settings. In dev / production, you add an environment variable to use the respective settings module (e.g., DJANGO_SETTINGS_MODULE=myproject.conf.dev).

When you use 12 Factor, it's no longer necessary to keep certain settings modules out of version control, because, with 12 Factor, you don't put any passwords or sensitive settings directly into a settings module. You instead keep them in the environment and access them like this:

# Inside of a settings module
FOO_PASSWORD = os.environ['FOO_PASSWORD']

In environments like Heroku, this setup is simple, because you can enter config vars for your app via the web interface.

I recommend pretty much all of 12 Factor's principles, esp things like disposability, logs, and config.

Reasonable sacrifice

If you'd like to maintain an extra settings module, out of version control, to avoid having to use environment variables during local dev (I don't blame you), you can still follow the above principles and also add, to the bottom of the local settings module that is in version control, try: from some_other_local import * except: pass. This will allow you to set only the necessary override settings locally, while still keeping the rest of your local settings (e.g., local database, relative static / media file paths, installed apps, etc.) in version control, which gives you the best of both worlds.

Extra Resources

  • https://github.com/joke2k/django-environ
  • https://github.com/doismellburning/django12factor
  • https://wellfire.co/learn/easier-12-factor-django/