Deploy Django App On Heroku (Full Guide)

Deploy django app on heroku. Django is a full stack python framework.

Important

If you have already created your virtual environment and your django app, then you can skip first few sections. In this post, we are going to learn how to deploy django app on heroku.

So, let’s begin.

1. Create A Django Project (Skip if already created)

I would like to make a directory first to keep my environment and my django project.

mkdir deploy_django
cd deploy_django

Now, we have to create a virtual environment for our project. We need virtual environment to confine python packages to our scope only. Here, I gave it name env, however you can choose any name.

python -m venv env

We have to install packages in our virtual environment. First package that we want to install will be django.

pip install django

Now, create a django project in the same folder. I gave it name heroku_django. Remember the dot(.) at the end of the command

django-admin startproject heroku_django .

The trailing dot is required because it makes the current directory also the project directory.

Let’s perform initial migration to the database. By default, django uses sqlite database.

python manage.py migrate

If we now run the server, then you will get a landing page at http://127.0.0.1:8000/.

python manage.py runserver

In brief, we created a project till this point. Without delay, let’s move into configuring the app for production.

2. Configure environment variables for Heroku

We need environment variables in our program if we are to deploy our app. To put it another way, servers are configured using environment variables for our app.

Therefore, we have to change some lines in settings.py . At first, we have to set our secret key as environment variable. The first argument is environment variable, and second is default value if not in production.

import os

# SECURITY WARNING: keep the secret key used in production secret!

# SECRET_KEY = 'your-secret-key'
SECRET_KEY = os.environ.get('SECRET_KEY','your-secret-key')

After that, we need to set the DEBUG as environment variable.

# SECURITY WARNING: don't run with debug turned on in production!
# DEBUG = True
DEBUG = os.environ.get('DEBUG', '') != 'False'

This will make DEBUG to be True by default, and you have to set environment variable DEBUG to False.

# In windows
SET DEBUG=False
# In Linux
export DEBUG=False

Up to now, the configuration we have done is at least to be done for deployment, however, you can find all options by running following command

python manage.py check --deploy

3. Requirements For Heroku

Now, we have to configure our django app to be ready for heroku. Having said so, we have to identify the files heroku requires for the production. The files that heroku needs are stated below:

  1. runtime.txt: This file has the version of python which the app uses. For example, python-3.7.2 .
  2. requirements.txt: This file contains all the packages that our app requires.
  3. Procfile: A list of processes to be executed to start the web application. For Django this will usually be the Gunicorn web application server (with a .wsgi script).
  4. wsgi.py: WSGI configuration to call our Django application in the Heroku environment.

You can find your python runtime by running following command. Simply create a file and paste python-<your version> in the file.

python -V

I hope you don’t have a requirements.txt file, which you can create by running following command

pip freeze > requirements.txt

Now, you can see a requirements.txt file with packages and their respective versions.

Again, you have to create a file Procfile where you should paste a line as:

web: gunicorn heroku_django.wsgi --log-file -

Please check, WSGI_APPLICATION in your settings.py to know the name.

4. Proceeding with Heroku

To deploy the django app on heroku, at first, you have to create an account in Heroku. After that, you can download heroku-cli client from its website and then install it.

Now, you have to initialize git for your project directory if you haven’t. Also, we don’t want our packages to be in our git repo, hence add the environment env/ and other IDE or text editors created folder in .gitignore. So, open or otherwise create .gitignore and paste following

env/
.idea/
.vs/

After this, you can add all your files and commit them in the repo by

git add .
git commit -m "Initial Commit"

Now, we have to create a heroku app, which is unique. The heroku app is browsed in the internet as <herokuapp-name>.herokuapp.com . For this, I hope you have already installed heroku and selected the option to add heroku to the path.

heroku create <unique-app-name-not-served-in-heroku>

If you omit, the app name, it will automatically select a name for your app. You will be asked for some authentication mechanism, which you should proceed.

I have used my name as djangonepcodex. So, I need to add my app to the ALLOWED_HOSTS options in settings.py as below. Using the similar technique, you have to add yours host.

ALLOWED_HOSTS = ['djangonepcodex.herokuapp.com', '127.0.0.1']

Now, before adding our git repo to heroku, let’s make some changes in our settings.py file.

5. Changes in settings.py file of our Django project

You have to install gunicorn for the http server to use in Heroku.

pip install gunicorn

Now, we have to configure database for our app. dj-database-url is required to configure the database. Also, heroku uses postgresql for its database, hence we require psycopg2 module to interact with it.

pip install dj-database-url psycopg2

Now, open settings.py and paste the following lines into the bottom of the file:

# Heroku: Update database configuration from $DATABASE_URL.
import dj_database_url
db_from_env = dj_database_url.config(conn_max_age=500)
DATABASES['default'].update(db_from_env)

We have to serve static files in production which is different from development. To fulfil that, we have to make some changes in settings.py file.

# The absolute path to the directory where collectstatic will collect static files for deployment.
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')

# The URL to use when referring to static files (where they will be served from)
STATIC_URL = '/static/'

You can run python manage.py collectstatic to create the staticfiles directory. Also, you can give staticfiles any name you want.

We’ll actually do the file serving using a library called whitenoise, which we install and configure.

pip install whitenoise

To install whitenoise into our Django application, in settings.py, find the MIDDLEWARE option and then, add the WhiteNoiseMiddleware near the top of the list, just below the SecurityMiddleware as follows:

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'whitenoise.middleware.WhiteNoiseMiddleware',
    ...
]

Also, you may want to compress the files for better serving. For that, add a line in settings.py file:

STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'

Now, update the requirements.txt file as below

pip freeze > requirements.txt

Let’s Move onto Heroku again

Let’s add remote for the heroku as following:

heroku git:remote -a <your_heroku_app_name>

For me it is

heroku git:remote -a djangonepcodex

Now, add changes to the git.

git add .
git commit -m "Changed the settings file for deployment"

After this, we have to push into the heroku.

git push heroku master

Up to this point, dependencies are installed in our heroku server, however we have not configured our database in our remote app. So, let’s migrate into database of our heroku app by

heroku run python manage.py migrate

It also starts a running instance in web.

You should note that, we haven’t set an environment variable in remote side (heroku). Hence, we need some configuration related to our project in heroku. For that let’s list our config vars.

heroku config

Here, we can see database configuration only. So, let’s add DEBUG and SECRET_KEY. which is important to do.

heroku config:set DEBUG=False
heroku config:set SECRET_KEY="<Your secret key>"

Confirm your variables again.

heroku config

Please note that, environment variables are of string type, hence whatever you see while running above command, it is a string and not any other type. It is the reason why we set DEBUG variable a string.

Finally add a line for logging collectstatic

heroku config:set heroku config:set DEBUG_COLLECTSTATIC=1

What to do next after deploying django app on heroku?

There are many things, which you can do next. For example, you can add github remote to your project which will make it easier for your collaborators to work with you. Additionally, you can connect your github with your heroku app from the dashboard in heroku. Doing so, if any of your collaborators push any changes to the github, it will automatically updated in heroku as well. Give it a try yourselves.

I hope this tutorial has become helpful to deploy your django app on heroku.

If you want to learn about Django Rest API, you can find it here: https://nepcodex.com/blog/2019/07/django-rest-api-from-scratch-part-1/

Also, if you want to develop react app with redux and router, you can see this guide: https://nepcodex.com/blog/2019/07/a-guide-to-react-redux-router-latest-version/

3 thoughts on “Deploy Django App On Heroku (Full Guide)”

  1. Wooow, great article, it worked like a charm!, I have only one question, where do we get the environment variables from? for example in this part
    SECRET_KEY = os.environ.get(‘SECRET_KEY’,’your-secret-key’)

    Where is ‘SECRET_KEY’?

    Reply
    • You might be familiar with the concept of environment variables in operating systems. These variables can be accessed in the scope of system, user or a session. For example, in Linux, your home directory is stored in a variable ‘HOME’. So, when you enter the command echo $HOME in your terminal, you will print the path of your home directory. Likewise, in heroku, you can define environment variables for your app. In the article, we set environment variables through heroku cli. You can log into the dashboard to see what your variables are. You can set any of them as per your requirement.

      Reply

Leave a Reply

%d bloggers like this: