Creating Dev, Staging and Production Environments Configurations in Django
Why? #
Whenever you start with a scaffolded Django project form the beginning you have one large settings.py
that contains all the application settings details. This is fine for early development, but when you begin to deploy the application and have multiple environments dev
, staging
, production
your application can become less secure if you do not adopt a strategy for handling these different environment.
The .env file - It is your friend (So Are Environment Variable in General). #
The .env file will allow you a place to abstract a set of values that you may want to interchange based on the configuration environment that you are in.
Two common values in the Django could be SECRET_KEY
and DEBUG
.
A .env
stored in your root directory in your project could be accessed in other places of you application. This .env
would allow you to change Debug
mode from False to True just by provide a single configuration change and not needing to update you code.
Here is how you could read those values in an example inside of a Python Codebase
Configuring Different Environments #
The first thing that I would do here is move away from the long settings.py
method of organization and think in a paradigm of Common Shared Values and Environment Specific Values.
Common Shared Values in Django (few examples)
- INSTALLED_APPS
- MIDDLEWARE
- WSGI_APPLICATION
- LANGUAGE
Environment Specific Values (few examples)
- DEBUG
- SECRET_KEY
- DATABASES
Environment Specific values relate to anything that could change. Often times we find it better to have a different database for Local Development, Staging and Production so we can test code differently without effecting Production. These lists are exhaustive but a starting point to look at.
Structuring Configuration Environments #
First thing in would create a folder structure like the following:
Project Structure for Environment Configs for Django Application
In __init__.py
I would make sure that I am exporting all the newly created settings files.
settings/init.py
Development environment #
Next, I would remove all Environment Specific variables from settings/common.py
(Originally a clone of settings.py
) and move them over to settings/development.py
leaving me with a settings/common.py
file that has variable/settings necessary across all environments.
settings/common.py (truncated)
Next, I would go to my settings/development.py
and import the common.py
settings first. Doing this would allow me to change my to DJANGO_SETTINGS_MODULE=<project_name>.settings.development
and the project would first inherit all the settings from settings/common.py
then settings/development
and using the environment variables from our .env
file in both places.
settings/development.py (example)
Staging and Production #
Now that we have a running Development configuration setting up a staging or production environment is as simple as creating settings/staging.py
and a settings/production.py
Below is an example of how staging and prod files can differ from development.
To use this staging you would just call DJANGO_SETTINGS_MODULE=<project_name>.settings.staging
and production would be DJANGO_SETTINGS_MODULE=<project_name>.settings.production
settings/staging.py or settings/production.py (example)
With this approach you will be able to have environment specific variables and common shared settings. To me this is a clean approach to splitting up a Django application to support different environments.