Deploying Django to production

Overview

Once your site is finished (or finished “enough” to start public testing) you’re going to need to host it somewhere more public and accessible than your personal development computer.

Up to now you’ve been working in a development environment, using the Django development web server to share your site to the local browser/network, and running your website with (insecure) development settings that expose debug and other private information. Before you can host a website externally you’re first going to have to:

  • Make a few changes to your project settings.
  • Choose an environment for hosting the Django app.
  • Choose an environment for hosting any static files.
  • Set up a production-level infrastructure for serving your website.

This tutorial provides some guidance on your options for choosing a hosting site, a brief overview of what you need to do in order to get your Django app ready for production.

Getting your website ready to publish

The Django skeleton website created using the django-admin and manage.py tools are configured to make development easier. Many of the Django project settings (specified in settings.py) should be different for production, either for security or performance reasons.

Critical settings

  • SECRET_KEY: This is a large random value used for CRSF protection etc. It is important that the key used in production is not in source control or accessible outside the production server.

Instead of hardcoding the secret key in your settings module, consider loading it from an environment variable:

import os
SECRET_KEY = os.environ['SECRET_KEY']

or from a file:

with open('/etc/secret_key.txt') as f:
    SECRET_KEY = f.read().strip()
  • DEBUG: This should be set as False in production (DEBUG = False). This stops the sensitive/confidential debug trace and variable information from being displayed.

Environment-specific settings

  • ALLOWED_HOSTS: When DEBUG = False, Django doesn’t work at all without a suitable value for ALLOWED_HOSTS.

  • STATIC_ROOT and STATIC_URL

    • Install:
      pip install WhiteNoise
      
    • And change your wsgi.py file to this:
      from django.core.wsgi import get_wsgi_application
      from whitenoise.django import DjangoWhiteNoise
      application = get_wsgi_application()
      application = DjangoWhiteNoise(application)
      
    • Project settings
        STATIC_URL = '/static/'
        STATIC_ROOT = os.path.join(BASE_DIR, "static")
      

Performance optimizations

  • TEMPLATES

    
      TEMPLATES = [
          {
              'BACKEND': 'django.template.backends.django.DjangoTemplates',
              'DIRS': [os.path.join(BASE_DIR, "template"),
                       os.path.join(BASE_DIR, "pages")],
              'APP_DIRS': True,
              'OPTIONS': {
                  'context_processors': [
                      'django.template.context_processors.debug',
                      'django.template.context_processors.request',
                      'django.contrib.auth.context_processors.auth',
                      'django.contrib.messages.context_processors.messages',
                  ],
              },
          },
      ]