/ code

Deploying a Django App to Heroku

So you have developed your new shinny app. It's time to show the world what you have got. But it quickly hits you that development, deployment and production are completely different things.

How do you move from localhost to cloud with a lot more ease?

The conventional way is to signup (with a credit/debit Visa card) for an account on a cloud provider such as Digital Ocean or Linode or AWS, spin up a minimal Virtual Machine of say $10/month. Then install system and application packages and dependencies to replicate your local development environment, configure DNS and finally (hopefully) launch you app. That's a long and painful process if all you have is just a to-do app you want to share with your friends.

Heroku is a PaaS or Platform-As-A-Service provider. They provider the infrastructure and platform via a couple of tools so you can launch your app to the world without worrying about underlying infrastructure. Heroku supports node, ruby, python, go, scala, Java and Clojure languages as of 2018.

Heroku has a free plan as long as your app doesn't consume resources up to a certain limit beyond which the billing meter will kick in. This makes it great for prototyping and learning. But if you are ready for production, then you have to choose between continuing with their platform or go with a VPS on Linode or Digital Ocean.

To deploy your Django app to heroku, you need to add three files to your app root folder;

  • runtime.txt
  • Procfile
  • requirements.txt

runtime.txt

runtime.txt is where you put the python version that your app runs on. For instance python-3.6.6 if your app is running on python 3.6.6.

Procfile

Create a Procfile file and add the following to it;
web: gunicorn {app_name}.wsgi --log-file -

Gunicorn or 'Green Unicorn' is a Python Web Server Gateway Interface (WSGI) HTTP Server for UNIX systems. WSGI server runs Python code to create a web application.

Heroku uses Gunicorn to run Python application such as those created using Django Framework concurrently by running multiple Python processes within a single dyno. According to Heroku, it provides a perfect balance of performance, flexibility, and configuration simplicity. You can read more about that on heroku documentation page.

That said, gunicorn must be part of your application dependencies which we shall talk about next.

The --log-file flag lets you set a path to a log file, and - means "stdout" (in this context).

requirements.txt

This file holds a list of python libraries that your Django app depends on. Usually these are installed like so pip install -r requirements.txt upon deployment.

Since this is a django App, then you must include django in requirements.txt. You can automatically generate a requirements.txt file by running pip freeze > requirements.txt. You can read more about requirements.txt file in the Python documentation site.

Sample requirements.txt file

Django==2.0
django-heroku==0.3.1
gunicorn==19.7.1
whitenoise==3.3.1

Project structure

Generally, your project structure should be something like;
[email protected] (dev2) % tree -L 1
├── accounts
├── dashboard
├── db.sqlite3
├── manage.py
├── myapp
├── Procfile
├── requirements.txt
├── runtime.txt
├── static
├── templates

Deploying to Heroku

If you got this right, then then the hard part is done. All you have to do now is simply create an account with heroku. Then use heroku command line tools and git to deploy the project.

There are several ways of installing Heroku command line tools to your operating system. For Ubuntu the easiest way is simply to run the command curl https://cli-assets.heroku.com/install-ubuntu.sh | sh which is a bash script that downloads on your pc and runs the installation.

After you install the CLI, run the heroku login command to log in with your Heroku account credentials.

[email protected] (dev2) [2] % heroku login
heroku: Enter your login credentials
Email [[email protected]]: 
Password: ********
Logged in as [email protected]

Now you are ready to push an App to heroku. Login to the dashboard and create an app. The app name must be unique since it will run on a unique heroku.com subdomain.

For instance if your app name is daveapp1, then you start by creating a new Git repository like so;

$ cd my-project/
$ git init
$ heroku git:remote -a daveapp1

To deploy your application, commit your code to the repository and deploy it to Heroku using Git.

$ git add .
$ git commit -am "make it better"
$ git push heroku master

If you have an existing Git repository, simply add the heroku remote like so;

$ heroku git:remote -a daveapp1

Heroku will install all the app dependencies in requirements.txt and launch your app. You can access your app from {app_name}.heroku.com if everything checkouts out.

However, we don't leave in an ideal world. You will run into errors. This is where Heroku app logs come in handy.

You should be able to view console output so you can troubleshoot your app.

Make migrations on Heroku

Making migrations is an important part of deploying a django app on any environment. Migrations makes django create the necessary database tables based on your models. So to run migration on your remote django app on Heroku, run
heroku run python manage.py migrations.

Serving static files

This is the annoying part about django-heroku deployment. When deploying a django app, you run python manage.py collectstatic. collectstatic will then collect static files from all the apps in one place so that it could be served up from a single place on a production environment. When you are deploying to heroku, then is done automatically.

WhiteNoise is python package that allows your web app to serve its own static files, making it a self-contained unit that can be deployed anywhere.

Open your settings.py and add the following to configure whitenoise with django;

MIDDLEWARE = [
    ....
    'whitenoise.middleware.WhiteNoiseMiddleware',
]
STATICFILES_STORAGE = 'whitenoise.django.GzipManifestStaticFilesStorage'

So that's how briefly you can deploy your django app on Heroku PaaS platform.

Deploying a Django App to Heroku
Share this

Subscribe to David Okwii dev blog