In a previous blog post, we explained how we enhanced a Django application to make it compatible with a wide range of Python/Django versions. In this blog post, we explain how we deployed a demo application on Heroku.

Deploying a Django demo application on Heroku from a sandbox

In order to test a Django application, a best practice is to have a sandbox of a Django project to run the tests in it. Since we have a functioning project into the repository (cf. How-To: enhance the Python + Django compatibility of a Django application), why not reusing it to show a demo? That is what we have done for the Django TailorDev Biblio project and we tell you how we deployed it to Heroku in the sequel.

Heroku is a platform as a service (PaaS) that enables developers to build, run, and operate applications entirely in the cloud. It takes care of most of the annoying things related to software deployment.

Project configuration

In order to deploy the sandbox to Heroku, you will have to create two (Heroku-) specific files (Procfile and runtime.txt) at the root of the project:

$ echo 'web: gunicorn sandbox.wsgi --log-file -' > Procfile
$ echo 'python-3.6.1' > runtime.txt

The runtime.txt file tells Heroku which Python version must be used for the project while the Procfile states how to run it. In our case, we use the gunicorn WSGI server.

Python requirements

The project requirements.txt file must include all the required dependencies to run on Heroku. It includes common Django dependencies such as gunicorn and psycopg2) as well as less common ones, namely dj-database-url and whitenoise, which will be described later.

# requirements.txt

# WSGI
gunicorn

# Database
psycopg2

# Settings
dj-database-url

# Statics
whitenoise

Settings

You will also have to adapt your sandbox settings as follows:

# sandbox/settings.py

import os
import dj_database_url


BASE_DIR = os.path.dirname(os.path.abspath(__file__))

# Default secret key is for development only!
SECRET_KEY = os.environ.get(
    'DJANGO_SECRET_KEY',
    'this_is_my_default_key_for_development'
)

# DEBUG is turned off if IS_PUBLIC_SANDBOX environment variable is defined
DEBUG = os.environ.get('IS_PUBLIC_SANDBOX') is None

# Application definition
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'whitenoise.runserver_nostatic',  # use whitenoise in development
    'django.contrib.staticfiles',
    'my_app',
]

MIDDLEWARE = (
    'django.middleware.security.SecurityMiddleware',
    'whitenoise.middleware.WhiteNoiseMiddleware',  # serve static files
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
)

DATABASES = {
    'default': dj_database_url.config(conn_max_age=600),
}

# Static files (CSS, JavaScript, Images)
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'public', 'static')
STATICFILES_DIRS = (
    os.path.join(BASE_DIR, 'static'),
)

As you may have noticed, we configure two unusual dependencies in this sandbox/settings.py file:

  • whitenoise: a wonderful application used to serve static files;
  • dj-database-url: a small utility to configure your database-related settings with an URL that can be found in a DATABASE_URL environment variable (supplied by Heroku).

The project is now properly configured to run on Heroku (and also other PaaS by the way).

Heroku configuration

You will need to login to your Heroku account (or create an account first). Once logged in, create a new application and connect it to your GitHub project:

tailordev-biblio Heroku

Configuration variables

Configuration variables are environment variables forwarded to your application. You will have to create two variables via the Heroku dashboard:

  • DJANGO_SECRET_KEY: this will be your instance secret key (see the Django documentation for further information);
  • IS_PUBLIC_SANDBOX: set this value to 1 or anything you want as long as it exists, it will inactivate the DEBUG mode (cf. Settings).

Note that the DATABASE_URL variable is automatically created for Django applications pushed to Heroku \o/

Perform database migrations

Install the Heroku Command Line Interface (one of the best CLI I have ever used :heart:), and then login to perform database migrations:

$ heroku login
$ heroku run -a my_app python sandbox/manage.py migrate

In this example, we assume that the application is registered as my_app on Heroku. And voilà! Your app should be up and running at: https://my_app.herokuapp.com/.

Mission accomplished


You will find the demo of our Django TailorDev Biblio project at: tailordev-biblio.herokuapp.com. It might take a while since Heroku “lazy-starts” applications running on free plans, which is perfectly fine for demo :wink: