Deploy Django App On Heroku (Full Guide)

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:
- runtime.txt: This file has the version of python which the app uses. For example,
python-3.7.2
. - requirements.txt: This file contains all the packages that our app requires.
- 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). - 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/