Introduction
The Django startproject command creates a settings file that includes values that should be kept secret. These include:
SECRET_KEY is a value used when generating sessions and password reset tokens.
DATABASE_SETTINGS specifies the database connection settings and may include database credentials.
The DEBUG setting is also of interest:
DEBUG is a boolean value which determines whether Django displays detailed tracebacks are displayed when exceptions are raised.
The deployment checklist recommends that:
- DEBUG be set to False to avoid leaking sensitive information from the detailed tracebacks that Django displays
- Secrets and database credentials be kept out of source control.
This is also consistent with the Twelve-factor recommendation to keep Config separate from Code.
Twelve-factor is a useful set of recommendations for building web applications.
Django-environ
Django-environ is a third-party Django library that can be used to manage environment variables.
Values are read on startup instead of hardcoded in the settings file. The benefits include:
- Your don't have to use multiple settings files to manage different deployments (e.g staging, production, developer).
- Secrets can be kept out of source control.
It reads values from a .env file in the same folder as settings.py.
Instructions
Note: In the instructions below .env.example and .env should be saved in the same folder as settings.py
Install django-environ
pip install django-environ
Add a .env.example file with these contents:
DEBUG=on
SECRET_KEY=your-secret-key
DATABASE_URL=psql://urser:urpassword@127.0.0.1:8458/database
This file is an example for collaborators to follow when creating the .env file for their local environment.
Add .env
to your .gitignore file to prevent it from being added to the repository
At the top of your settings.py add the following:
import environ
env = environ.Env(
# set casting, default value
DEBUG=(bool, False)
)
# reading .env file
environ.Env.read_env()
Change the DEBUG, SECRET_KEY and DATABASES lines in settings.py to read their values from the environment.
DEBUG = env('DEBUG')
...
SECRET_KEY = env('SECRET_KEY')
...
DATABASES = {
'default': env.db(),
}
Your can then add .env.example
and the the modified settings file to the Git repository
git add .
git commit -m "Extracted secrets from the settings file"
For each deployment (staging, production, developer environment) you then:
Create a .env file with the settings specific to that environment. These include:
- Your desired DEBUG setting.
- The secret key.
- Your DATABASE connection string and credentials.
Django has a utility function that the startproject command uses to generate the secret
You can use it from the command line.
With your virtual environment activated run this command:
python -c 'from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())'
It will spit out a random string like:
a1$%jr29f2(u^l=r1q1a2$sztg%x7%g8s@!ne#_(^5$woi#wi$
Assuming your DATABASE setting was
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'blog',
'USER': 'dbuser',
'PASSWORD': 'dbpassword',
'HOST': '127.0.0.1',
'PORT': '5432',
}
}
Your .env file would look like
DEBUG=on
SECRET_KEY=a1$%jr29f2(u^l=r1q1a2$sztg%x7%g8s@!ne#_(^5$woi#wi$
DATABASE_URL=psql://dbuser:dbpassword@127.0.0.1:5432/blog
Note that there are not quotes around the values in the .env file
For your production deployment change DEBUG=on
to DEBUG=off
You can confirm that your app starts up successfully by running the Django Dev Server
python manage runserver
If there are any errors consult the Django-environ documentation for guidance.
Top comments (2)
Thank you
is it possible without django-environ?