Skip to content

Instantly share code, notes, and snippets.

@diegommarino
Last active April 12, 2018 17:10
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save diegommarino/66b4c91c0a8849cd42498991d21c748d to your computer and use it in GitHub Desktop.
Save diegommarino/66b4c91c0a8849cd42498991d21c748d to your computer and use it in GitHub Desktop.
Creating a Django sample app and deploying it to Heroku

Deploying a Django app to Heroku

This guide has the objective to show how to build a sample Django app and deploy it to Heroku. We'll go through the following steps:

  • Create a sample app
  • Database configuration
  • Configuring project to deploy to Heroku

I'll not cover how to install Django, Postgresql or configure python, assuming that you already have a configured environment.

Creating a sample app

Firstly, let's create a sample app, configure Postgresql database credentials and create a model. This is necessary so I can demonstrate how to configure the database later in Heroku. Our sample app will have just a model called quotes with a description attribute.

To begin the project create the project base folder, virtual environment and activate it.

$ mkdir quotes
$ cd quotes
$ virtualenv quotesenv
$ source quotesenv/bin/activate
$ pip install pipenv

Deploying an app to Heroku require a Pipfile file, that's why we are using pipenv lib. If the pipenv command is not available on the next steps you may need to reload the shell, using, for example, the command source ~/.bashrc or .zshrc if you are using zsh.

Next, start the project and create a quote app and model.

$ pipenv install django psycopg2 django-environ
$ django-admin startproject quotesapp
$ cd quotesapp
$ django-admin startapp quotes
$ mkdir quotes/models
$ touch quotes/models/__init__.py
$ touch quotes/models/quote.py

Put the following code in the quote.py model

# quotesapp/quotes/models/quote.py
from django.db import models


class Quote(models.Model):
    description = models.CharField(max_length=130)

and add the model to __init__.py file just created.

# quotesapp/quotes/models/__init__.py
from quotes.models.quote import Quote

All set, just need to install the app now. In settings.py file add the app to the project.

# quotesapp/quotesapp/settings.py
...

INSTALLED_APPS = [
    ...
    'quotes',
]

...

Database configuration

Alright, now let's change settings.py to configure the database and correctly execute makemigration and migrate commands. Don't forget to create a database with the name quotes. Open the settings.py file and configure the following parameters.

# quotesapp/quotesapp/settings.py
import os
import environ

env = environ.Env()
environ.Env.read_env() # reading .env file

...

# Local database configuration
DEFAULT_DB_URI = 'postgres://USERNAME:PASSWORD@localhost:5432/quotes'
DATABASES = {
    'default': env.db('DATABASE_URL', default=DEFAULT_DB_URI)
}

...

Since django-environ lib uses the the dj-database-url lib we can specify the database URI and it'll parse the configuration for us. The configuration added will look for an environment variable called DATABASE_URL and if none is found it will set a default value, that's the local database configuration stored in the DEFAULT_DB_URI variable.

With the database configured, run the migrations. From project root folder run

$ python manage.py makemigrations
$ python manage.py migrate

Nice! The project is finished and asking for a deploy configuration. To test if everything is ok , run python manage.py runserver to start the server and access localhost:8000 to check if the project is running.

Configuring project to deploy to Heroku

First of all, you need to install Heroku CLI. Their installation tutorial can be found in this https://devcenter.heroku.com/articles/heroku-cli. You'll need to create an account in the [https://www.heroku.com/](Heroku website) too.

Heroku uses gunicorn by default to run the app, so install it.

$ pipenv install gunicorn

Now in the project root folder, create a file called Procfile with the following content.

web: gunicorn wsgi  --log-file -

When deployed to Heroku the Procfile will be executed to run the app. Now change the settings so the app initializes the secret key from an environment variable.

# quotesapp/setting.py
...

SECRET_KEY = env('SECRET_KEY', default='ANY_SECRET_KEY')

...

Using the Heroku CLI execute the following commands to log in, create an app, add the PostgreSQL database and add a random secret to Heroku env variables.

$ heroku login
$ heroku create APP_NAME_IS_OPTIONAL
$ heroku addons:create heroku-postgresql:hobby-dev
$ heroku config:set SECRET_KEY=$(python -c 'import random; import string; print("".join([random.SystemRandom().choice("{}{}{}".format(string.ascii_letters, string.digits, string.punctuation)) for i in range(50)]))')

[https://devcenter.heroku.com/articles/heroku-postgresql](Oficial Heroku Postgres docs). Credits to fjsj user in [https://gist.github.com/ndarville/3452907](this post) about how to generate random keys and set it in Heroku.

When a new Heroku app is created its name will appear in the console. Add this name combined with Heroku base URL to the ALLOWED_HOSTS in the settings.py file. Also, add a STATIC_ROOT variable where the static files will be served.

# quotesapp/quotesapp/settings.py
...

ALLOWED_HOSTS = ['HEROKU_APP_NAME.herokuapp.com']

...

STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
STATIC_URL = '/static/'

Since the code from this guide at this point is not versioned yet, and Heroku only deploys versioned codes, we need to start git on the project. Enter in the project root and initialize it.

$ git init
$ printf '.env' >> .gitignore
$ git add --all
$ git commit -m "First commit"

.env was added to .gitignore to avoid upload it in version control, so everyone would see the API URL and password for example. This project is not using a .env file, but warnings are never too much.

And finally, to deploy the app, we now just need to push it to Heroku.

$ git push heroku master
$ heroku open

Conclusion

That's it. It is pretty straightforward to deploy a Django app to Heroku. There a plenty of other configurations you can set in Heroku for your project, like using whitenoise lib to compress your assets. You can go to the official Heroku documentation and explore some of them. This guide was build base on the official step-by-step Django deploy to Heroku (https://devcenter.heroku.com/articles/getting-started-with-python).

@Ziggoto
Copy link

Ziggoto commented Apr 11, 2018

Top <3

@wilmersondasilva
Copy link

Nice job!!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment