Django Using Environment variables to manage Settings across servers


Example

Using environment variables is a widely used way to setting an app's config depending on it environment, as stated in The Twelve-Factor App.

As configurations are likely to change between deployment environments, this is a very interesting way to modify the configuration without having to dig in the app's source code, as well as keeping secrets outside the application files and source code repository.

In Django, the main settings are located as settings.py in your project's folder. As it is a simple Python file, you can use Python's os module from the standard library to access the environment (and even have appropriate defaults).

settings.py

import os

SECRET_KEY = os.environ.get('APP_SECRET_KEY', 'unsafe-secret-key')

DEBUG = bool(os.environ.get('DJANGO_DEBUG', True) == 'False')

ALLOWED_HOSTS = os.environ.get('DJANGO_ALLOWED_HOSTS', '').split()

DATABASES = {
    'default': {
        'ENGINE': os.environ.get('APP_DB_ENGINE', 'django.db.backends.sqlite3'),
        'NAME': os.environ.get('DB_NAME', 'db.sqlite'),    
        'USER': os.environ.get('DB_USER', ''),
        'PASSWORD': os.environ.get('DB_PASSWORD', ''),
        'HOST': os.environ.get('DB_HOST', None),
        'PORT': os.environ.get('DB_PORT', None),
        'CONN_MAX_AGE': 600,
    }
}

With Django you can change your database technology, so that you can use sqlite3 on your development machine (and that should be a sane default for committing to a source control system). Although this is possible it is not advisable:

Backing services, such as the app’s database, queueing system, or cache, is one area where dev/prod parity is important. (The Twelve-Factor App - Dev/prod parity)

For using a DATABASE_URL parameter for database connection, please take a look at the related example.