Heroku is a cloud application platform, it is basically a Platform-as-a-Service (PaaS). They support several programming languages, including Python. It is very easy to deploy Django applications on Heroku. They also offer a free plan, which is quite limited, but it is great to get started and to host demos of Django applications.
Install Heroku Toolbelt
Actually, first thing – sign up to Heroku. Then install the Heroku Toolbelt. It is a command line tool to manage your Heroku apps.
After installing the Heroku Toolbelt, open a terminal and login to your account:
Preparing the Application
In this tutorial I will deploy an existing project, Bootcamp. It’s open-souce Django project I’ve developed a couple of years ago, and it’s also available on GitHub, so you actually can clone the repository and try it by yourself.
Basically things will work better if you are already using Git. The Heroku deployment process is done through Git. Your application will be stored in a remote Git repository in the Heroku Cloud.
Anyway, here is the list of things you will probably need to add to your project:
- Add a Procfile in the project root;
- Add requirements.txt file with all the requirements in the project root;
- Add Gunicorn to requirements.txt;
- A runtime.txt to specify the correct Python version in the project root;
- Configure whitenoise to serve static files.
The Procfile
Create a file named Procfile in the project root with the following content:
Note: change bootcamp with the name of your Django project.
The requirements.txt
If you are using a virtualenv and pip you can simply run:
Otherwise, list the dependencies like the example below. This is how a requirements.txt looks like:
The runtime.txt
Create a file named runtime.txt in the project root, and put the specific Python version your project use:
See the complete list of Heroku Python Runtimes.
Set Up The Static Assets
Configure the STATIC-related parameters on settings.py:
Install the Whitenoise, and don’t forget to update the requirements.txt:
Add the Whitenoise to your Django application in the wsgi.py file:
Update the settings.py
Optional
Here are two libraries I always use when deploying to Heroku, they are not required but they help a lot:
- python-decouple: Strictly separate the settings parameters from your source code. I’ve written an article about it, click here to learn more.
- dj-database-url: This simple Django utility allows you to utilize the 12factor inspired DATABASE_URL environment variable to configure your Django application.
You will see how I use it later on.
Deployment
Alright, enough configuration. Let’s get the deployment started.
First, clone the repository you want to deploy:
Login to Heroku using the toolbelt:
Inside the project root, create a Heroku App:
Output:
You can omit the app name parameter (in my case, demo-bootcamp), then Heroku will pick a name for you.
Add a PostgreSQL database to your app:
Output:
Now login to Heroku Dashboard and access your recently created app:
Click on the Settings menu and then on the button Reveal Config Vars:
Now we need to add all the Environment variables. Here is where python-decouple and dj-database-url are handy. Here is the list of variables I use on the Bootcamp project:
settings.py
The DEBUG var defaults to False
, and DATABASE_URL is automatically added by Heroku upon PostgreSQL database
installation. So in this case I will only need to add the SECRET_KEY:
Push to deploy:
Output:
Migrate the database:
Output:
And there you go! Try the URL in a web browser: http://demo-bootcamp.herokuapp.com/.
Wrap up
This is pretty much it. Heroku is a great service, but it is kinda expensive. For some hobby/non-production applications you can find some cheaper alternatives.
Be aware of some limitations of the free tier:
- The application “sleeps” after 30 minutes of inactivity. The first access after it might be slow.
- The free PostgreSQL database has a limitation of 10K rows.
Also if you need to store user uploaded files (media), you will need a service to store the files. The most common option is Amazon S3. This applies to every tier.