Chapter 6. Deploy Django App

Django Production Settings (3) – django-environ and .env file

Django Production Settings (3) – django-environ and .env file
Tag:

As explained on the previous page, we need to manage confidential data relating to the Django app settings. To separate the settings, you can use the django-environ library.

django-environ

django-environ allows you to configure the Django application using environment variables obtained from an environment file and provided by the OS.

Basically, using this library, you can separately manage confidential information in another file named .env.

Settings written in the .env file

Confidential data should be put in the .env file. Most confidential data are already included in the settings for production explained on the previous page, except SECRET_KEY. SECRET_KEY is not specific for production, but it should be confidentially managed and saved under the .env file.

IdeaNote: SECRET_KEY

According to the Django official documentation, SECRET_KEY is used to provide cryptographic signing and should be set to a unique, unpredictable value. Running Django with a known SECRET_KEY defeats many of Django’s security protections and can lead to privilege escalation and remote code execution vulnerabilities.

When you initiated the Django project, the secret key was already generated, and you can use it for production; however, you should not expose it to the public. In practice, you need to make sure that you won't push the information to the GitHub repository.

Key steps to use django-environ

Here are the key steps to use django-environ for our Django app.

1. Install django-environ

Add django-environ in requirements.txt and install the package.

requirements.txt
Django==4.1.7
django-crispy-forms
crispy-bootstrap5
django-allauth
django-environ

As we haven't created the virtual environment, actual installation will be done later in this chapter.

2. Edit production.py

First, you need to import environ, and add initial settings to read the .env file.

config/settings/production.py
from .base import *
import environ

env = environ.Env()
env.read_env('.env')

Then, bring the settings for production from the base.py file.

And replace confidential data with env('ENVIRONMENT_VARIABLE'). If there is a list of parameters, use env.list('ENVIRONMENT_VARIABLE').

Here is an example of production.py for our Django app. We don't include email settings and STATIC_ROOT here yet. We'll explain them later.

config/settings/production.py
from .base import *
import environ

env = environ.Env()
env.read_env('.env') 

SECRET_KEY = env('SECRET_KEY')

DEBUG = False

ALLOWED_HOSTS = env.list('ALLOWED_HOSTS')

DATABASES = {
    'default': {
        'ENGINE': env('DB_ENGINE'),
        'NAME': env('DB_NAME'),
        'USER': env('DB_USER'),
        'PASSWORD': env('DB_PASSWORD'),
        'HOST': env('DB_HOST'),
        'PORT': env('DB_PORT'),
    }
}

And this is the example of the .env file. Make sure that the .env file is created directly under the project directory.

.env
SECRET_KEY=django-insecure-a6e%75-^!....

ALLOWED_HOSTS=localhost,xx.xx.xx.xx

DB_ENGINE=django.db.backends.postgresql
DB_NAME=project_d
DB_USER=project_d_user
DB_PASSWORD=project_d_pass
DB_HOST=localhost
DB_PORT=5432

There are some points you need to be careful about.

  • no ' ' (quotation) for all settings
  • For ALLOWED_HOSTS, you need to put the static IP address that is attached to the Ubuntu instance. Keep localhost for testing purposes. When you write more than two hosts, make sure that there are no [ ] (brackets) and no space
  • For database settings, make sure that the values are the same as the ones you set when you created the database.

As explained on the previous page, we need to manage confidential data relating to the Django app settings. To separate the settings, you can use the django-environ library.

django-environ

django-environ allows you to configure the Django application using environment variables obtained from an environment file and provided by the OS.

Basically, using this library, you can separately manage confidential information in another file named .env.

Settings written in the .env file

Confidential data should be put in the .env file. Most confidential data are already included in the settings for production explained on the previous page, except SECRET_KEY. SECRET_KEY is not specific for production, but it should be confidentially managed and saved under the .env file.

IdeaNote: SECRET_KEY

According to the Django official documentation, SECRET_KEY is used to provide cryptographic signing and should be set to a unique, unpredictable value. Running Django with a known SECRET_KEY defeats many of Django’s security protections and can lead to privilege escalation and remote code execution vulnerabilities.

When you initiated the Django project, the secret key was already generated, and you can use it for production; however, you should not expose it to the public. In practice, you need to make sure that you won't push the information to the GitHub repository.

Key steps to use django-environ

Here are the key steps to use django-environ for our Django app.

1. Install django-environ

Add django-environ in requirements.txt and install the package.

requirements.txt
Django==4.1.7
django-crispy-forms
crispy-bootstrap5
django-allauth
django-environ

As we haven't created the virtual environment, actual installation will be done later in this chapter.

2. Edit production.py

First, you need to import environ, and add initial settings to read the .env file.

config/settings/production.py
from .base import *
import environ

env = environ.Env()
env.read_env('.env')

Then, bring the settings for production from the base.py file.

And replace confidential data with env('ENVIRONMENT_VARIABLE'). If there is a list of parameters, use env.list('ENVIRONMENT_VARIABLE').

Here is an example of production.py for our Django app. We don't include email settings and STATIC_ROOT here yet. We'll explain them later.

config/settings/production.py
from .base import *
import environ

env = environ.Env()
env.read_env('.env') 

SECRET_KEY = env('SECRET_KEY')

DEBUG = False

ALLOWED_HOSTS = env.list('ALLOWED_HOSTS')

DATABASES = {
    'default': {
        'ENGINE': env('DB_ENGINE'),
        'NAME': env('DB_NAME'),
        'USER': env('DB_USER'),
        'PASSWORD': env('DB_PASSWORD'),
        'HOST': env('DB_HOST'),
        'PORT': env('DB_PORT'),
    }
}

And this is the example of the .env file. Make sure that the .env file is created directly under the project directory.

.env
SECRET_KEY=django-insecure-a6e%75-^!....

ALLOWED_HOSTS=localhost,xx.xx.xx.xx

DB_ENGINE=django.db.backends.postgresql
DB_NAME=project_d
DB_USER=project_d_user
DB_PASSWORD=project_d_pass
DB_HOST=localhost
DB_PORT=5432

There are some points you need to be careful about.

  • no ' ' (quotation) for all settings
  • For ALLOWED_HOSTS, you need to put the static IP address that is attached to the Ubuntu instance. Keep localhost for testing purposes. When you write more than two hosts, make sure that there are no [ ] (brackets) and no space
  • For database settings, make sure that the values are the same as the ones you set when you created the database.
Tag: