Django Settings Deployment

Learn how to deploy Django settings into environment independent such as development and production

After a long research I have finally found a good solution to deploy Django settings into several stages, which is production, development and common shared settings.

I have also found a good way to deploy Django overall, which I'll be writing soon.

Just to clarify, there is not standard way of deploying Django, however I think the method I put together is a very good way for deployment.

1. Where should the settings be stored?

The settings are better accommodated within a settings module rather than a single settings.py file.

I've seen a lot of articles where people are storing everything in one single settings.py file and then at the bottom they include:

try:
from settings_local import *
except ImportError:
pass

Which means that settings variables from settings_local.py will override settings from settings.py. There is two options here and they are not good enough specially if you are using git or any other version control software.

Option 1:
Don't ever commit settings_local.py, but in this case you will have to keep your credentials and other sensitive information in settings.py, not good enough as they are not environment independent.

Option 2:
Same as above, however create a separate settings_local.py in the production environment and add the credentials and sensitive information there. Not good, because you can not version control and you will have to keep the settings remotely up-to-date, hard to keep track of.

2. How can I properly implement the settings to accommodate both environments?

This is where the settings module comes in very handy, let's break it down and create our settings module.

First let's see the Django directory structure when we create a new app with:

django-admin startproject my_app

Structure:

my_app/
manage.py
my_app/
__init__.py
settings.py
urls.py
wsgi.py

As you can see we have a single settings.py file.

Now let's go ahead and create the settings module directory.

Note: The settings directory needs to be at the same level as the settings.py and don't forget to create the file __init__.py, otherwise python will not recognise as a module.

Now we have an environment independent settings module, which is maintainable in both environments.

All you have to do now is include in dev.py and prod.py at the very top:

from .common import *

You can now override any settings variable according to the environment you are going to use.

Note: When you want to run the server or execute anything from manage.py, you will need to specifically tell Django that you want to load the specific settings.

To run the server on the local environment:

python manage.py runserver --settings=settings.dev

and for production:

python manage.py runserver --settings=settings.prod

3. What sensitive information should be separate from the main settings?

Now we have reached an important question, because the Internet is a hostile place, we don't want to expose sensitive information and we wan't to keep this information as hidden as possible from prying eyes.

This applies to database, email, secret key and anything with authentication related information.

Again there are a lot of article there suggesting you create a separate file for sensitive information and read it from settings.

Creating a file at /etc/my_app_settings.txt and setting strict permission is not a bad idea, however I think that environment variables are simpler and good for our use-case.

A good place to keep these environment variables is in the ~/bash_profile, so let's go ahead and create: