Dockerize Your Python Flask application and deploy it onto Heroku
By: Hari Krishnan U
Tags: Heroku, Dockerfiles, Docker, Python, Flask

In this blog, we can see how to dockerize a simple python flask app and deploy it onto Heroku. This blog assumes that you have already installed Docker and Heroku in your PC. If that’s not the case, you can easily install it from here and here.

At First, create a new directory my-dir and move inside the directory.

Create a python file named app.py with the following content in it

from flask import Flask, render_template

import os app = Flask(__name__) @app.route('/')

def fun():

return render_template('index.html') if __name__ == '__main__':

port = int(os.environ.get('PORT', 5000))

app.run(host='0.0.0.0', port=port, debug=True)

Create a new directory named templates (inside the my-dir directory) and inside it create a HTML file named index.html with the following content in it.

<!DOCTYPE html>

<html lang="en">

<head>

<title>Document</title>

</head>

<body>

<h1>Successfully dockerized your python app</h1>

</body>

</html>

Now create a requirements.txt with the following content in it.

Flask==1.1.1

Thus, we have created a basic flask app setup. Now, we need to dockerize the application.

Creating a Dockerfile

Inorder to dockerize our python Flask app, we need a Dockerfile which contains the instructions needed to build a Docker image, which contains the set of instructions for creating a docker container that can run on the docker platform.

Create a file named Dockerfile (Note: without any extensions) with the following content.

FROM python:3.6-buster

WORKDIR /app

COPY requirements.txt .

RUN pip install -r requirements.txt

COPY . .

CMD ["python", "app.py"]

For each instruction/command in the Dockerfile, the Docker image builder generates an image layer and stacks it upon the previous ones, thus each layer contains only the changes from the layers before it. Hence, the Docker image thus obtained is a read-only stack of the constituent layers.

Line by Line Explanation:

1. FROM python:3.6-buster

FROM allows us to build our required image over a base image. The base image we choose here is buster which is a Docker’s own “official” python image. This image itself is large, but these packages are installed via common image layers that other official Docker images will use, so the overall disk usage would be low.

2. WORKDIR /app

Set the present working directory.

3. COPY requirements.txt .

Copy the dependencies file from your host to the present working directory.

4. RUN pip install -r requirements.txt

To install all dependencies or pip packages.

5. COPY . .

Copy the rest of your app’s source code from your machine to the present working directory of the container.

6. CMD ["python", "app.py"]

CMD is the command to run on container start. It specifies some metadata in your image that describes how to run a container based on this image. In this case, it’s saying that the containerized process that this image is meant to support is python app.py. There can be only one CMD command per Dockerfile, if in case there is more, the last CMD command will take effect.

Now, we are done with all the source code we require. Currently the Directory structure will be as follows:

my-dir

----app.py

----templates

----index.html

----Dockerfile

----requirements.txt

Let’s Create the Docker image

Let’s build the Docker image locally and run to make sure that the service is running locally. Run the following command in your terminal to create the docker image from my-dir directory. The -t flag is used to give a name to the newly-created image.

$ docker image build -t my-app .

The above command may take upto 16 minutes to finish running, depending on your internet speed.

Run the below command to verify that you successfully built a docker image. If you see your image( my-app ) listed there, that means you are successful.

$ docker image ls

Run the docker container

$ docker run -p 5000:5000 -d my-app

In the above command the -p flag is used to publish a container’s port to the host. Here, we’re mapping port 5000 inside our docker container to port 5000 on our host machine so that we can access the app at localhost:5000 The -d flag runs the container in background and prints the container ID.

Check the localhost:5000 and if you see the heading “Successfully dockerized your python app”, then we successfully dockerized the app.

Stop and remove the docker container

The below command STOP and Remove the dockerized container from the localhost:5000. The container id is previously printed into the terminal.

$ docker container stop <container id>

$ docker system prune

Deploy onto Heroku

At first you need to login into the Heroku CLI.

$ heroku container:login

It would open the browser and prompt you to login with your Heroku credentials if you are not logged in already or if you are already logged in your Heroku account in your browser, just click Login on the new browser tab.

If you succeed in logging, you will receieve a message “Login Succeeded”.

Run the below command to create an app in Heroku, which prepares Heroku to receive your source code. Enter any name for your app. Heroku doesn’t allows to take names that’s already taken.

$ heroku create <name-for-your-app>

Now, you will receive a link like,

https://<name-for-your-app>.herokuapp.com/

Now, Run the below command to push the container into Heroku(the below command may take upto hours depending on your internet speed).

$ heroku container:push web --app <name-for-your-app>

.At this point, the docker container is pushed to Heroku, but not deployed or released. The following command would deploy the container.

$ heroku container:release web --app <name-for-your-app>

Now, the app is released and is running on Heroku and you can view it in the below site

https://<name-for-your-app>.herokuapp.com/

Thus, we successfully dockerized and deployed our Python Flask app onto Heroku.