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.
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',
]
...
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.
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
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).
Nice job!!!