How to deploy containerized Python and Django application on Heroku

This is the first time I have launched my python and django application(as a containerized application) on Heroku. First impression with Heroku is really great 🀩, because it provides lots of services and you can use the free services as well✌️. It did not ask me any credit card details like other cloud providers.

I will be covering here that how you can make your application as a containerized application to deploy on Heroku.

If you have any application which you have created, you can take that. I will be using my Converter Site application which can help me to deploy. Now we can dive into the steps

1.I have created Dockerfile which are mandatory instructions(which are not mandatory, I mentioned that this is for my application and you can skip) for any kind of web application created using Python and Django.

#Pull the base image
FROM python:3.7-slim

# who is the maintainer/author of this file
LABEL org.opencontainers.image.authors="PAYALSASMAL, [email protected]"

# set environment variables
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
ENV DEBUG 0

#upgrading pip for python
RUN python -m pip install --upgrade pip

#install tkinter for my application requirement, you can skip this for your application
RUN apt-get update && apt-get install -y tcl tk

#creating this dir for my application, you can skip this for your application
RUN mkdir -p /usr/share/man/man1

#installing libreoffice for my application, you can skip this for your application
RUN apt-get update && apt-get install -y \
    libreoffice-base default-jre

#copying requirements.txt file
COPY ./requirements.txt /app/requirements.txt

#install those requirements before copying the project
RUN pip install -r /app/requirements.txt

#copy the project
COPY . .

#run gunicorn. here pdfconverter is the project name
CMD gunicorn -b 0.0.0.0:$PORT pdfconverter.wsgi:application

PYTHONDONTWRITEBYTECODE: It prevents python from writing .pyc files to disc.

PYTHONUNBUFFERED: It prevents python from writing stdout and stderr stream. check this document for more info.

$PORT: This variable value will be set by Heroku at runtime.

2.Update the allow_host at settings.py. for your application.

ALLOWED_HOSTS = ['127.0.0.1']

3.Now test this application as a containerized application locally. So build the image using below command πŸ‘‡πŸ».

docker build -t pdfconverter:latest .

4.Now run that image using below command πŸ‘‡πŸ».

docker run --name pdfconverter -e "PORT=8000" -p 8007:8000 pdfconverter:latest

-e: I passed PORT as env variable. even though it will work without passing the env variable as well.

Here is an example
image

Make sure that your containerized application is working properly to the local at http://127.0.0.1:8007/ host.
image

5.As per requirements, I have added my below πŸ‘‡πŸ» requirements at requirements.txt file.

Django==3.2
djangoconvertvdoctopdf==1.0.1
gunicorn==20.1.0
pdf2docx==0.5.2
whitenoise==5.2.0
  • djangoconvertvdoctopdf: This module helps to convert from docx to pdf.
  • pdf2docx: This module helps to convert from pdf to docx
  • whitenoise: This module helps to manage the static media for your application. This need to be added as a middleware in Django settings.py
  • Django: This will install the django
  • gunicorn: This will install the gunicorn

6.We can add whitenoise middleware at settings.py.This middleware should be added after securityMiddleware.

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'whitenoise.middleware.WhiteNoiseMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

7.Configure staticfiles related stuffs at settings.py

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

STATIC_URL = '/static/'

STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'pdfconverter/static')
]

8.Let's create heroku application through Heroku Dashboard. Click on Create new app.

9.Provide a name of the app. As I have given pdfconverter-by-payal(as I created the app already with this name so it is showing that this name is not available). Then click on Create app button.

10.Click on Open app tab. This URL will be your application URL. It is https://pdfconverter-by-payal.herokuapp.com/ for my application.

11.We have to add the domain to settings.py without https.

ALLOWED_HOSTS = ['127.0.0.1','pdfconverter-by-payal.herokuapp.com']

12.Now we will be creating heroku.yml manifest file.

build:
  docker:
    web: Dockerfile
run:
  web: gunicorn pdfconverter.wsgi:application --bind 0.0.0.0:$PORT

As per manifest file document, heroku.yml manifest has 4 top-level sections:

  • setup - Specifies the add-ons and config vars to create during app provisioning
  • build - Specifies the Dockerfile to build
  • release - Specifies the release phase tasks to execute
  • run - Specifies process types and the commands to run for each

13.Now push your code to GitHub.

git push repo master

14.Install heroku cli in your local and then go to Heroku Dashboard under setting tab. check what is the stack here, stack should be heroku-20( which means ubuntu-20.04) by default.
image

15.Set the stack as container using below command πŸ‘‡πŸ».
image

16.Go to heroku dashboard. Click on Deploy tab. Click on GitHub under Deployment method. Authorized with your GitHub account and provide the repository name to connect.

17.Either you can choose automatic deployment(deploy application automatically on heroku after making changes on github) by click on Enable Automatic Deploys option or choose Manual Deploy by click on Deploy Branch. I have done Manual Deploy for my application.

18.You can see the logs if there is an issue while deploying, it will be failed.
image

19.I am able to see my application to https://pdfconverter-by-payal.herokuapp.com/ site and It is working as expected.

Note: You might not see the website,you might see the below error πŸ‘‡πŸ». so check the logs of application using heroku cli in your local.

Hope It will help someone πŸ€—.

Please note few things for my website:-

  • My website is not storing data inside the database so there is no data exposure, please feel free to use it.
  • This Converter Site is an open source. If you are an open source enthusiast, please feel free to contribute.

Let's connect on Twitter, LinkedIn and GitHub

28