# Dockerize a Python application.

## Dockerize a Python application - Intro

This article will show how to dockerize a simple Python application.

If you prefer a video version, you can find it here:

<iframe width="560" height="315" src="https://www.youtube.com/embed/zGP_nYmZd9c"></iframe>

All the code is available in the video description: [https://youtu.be/zGP\_nYmZd9c](https://youtu.be/zGP_nYmZd9c)

## 💡 Prerequisites

* Docker installed on your machine
    
* A Python application (we will use one by cloning a repository)
    

## 📥 Clone the GitHub repository

Clone the GitHub repository

```plaintext
git clone https://github.com/patrickloeber/ml-deployment.git
```

Now step into the `ml-deployment/docker-flask/app` directory

```plaintext
cd ml-deployment/docker-flask/app/api
```

Now open this directory in your favorite editor. If you are using VS Code, you can do this by typing

```plaintext
code .
```

⚠️ Since the repository is already the final version, if you want to follow along, delete the 2 files in the app/api directory:

* Dockerfile
    
* docker-compose.yaml
    

An alternative is to leave them as they are and just keep reading :)

## 🐳 Docker

When you open the project, you should have something like this:

[![project structure](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6gpyukjn1ryz2alo71j0.png align="left")](https://youtu.be/zGP_nYmZd9c)

We will create:

* a Dockerfile
    
* a docker-compose.yml file
    

### 🐋 Dockerfile

Create a file called `Dockerfile` in the `app` directory. This file will contain the instructions to build the Docker image.

```plaintext

FROM python:3.8

COPY requirements.txt .

RUN pip install -r requirements.txt

RUN python -c "import nltk; nltk.download('omw-1.4'); nltk.download('wordnet')"

COPY . .

EXPOSE 5000

CMD ["flask", "run", "--host=0.0.0.0", "--port=5000"]
```

Explanation of the `Dockerfile`:

* `FROM python:3.8`: Use the Python 3.8 image from Docker Hub
    
* `COPY requirements.txt .`: Copy the `requirements.txt` file from the current directory to the Docker image
    
* `RUN pip install -r requirements.txt`: Install the dependencies from the `requirements.txt` file
    
* `RUN python -c "import nltk;` [`nltk.download`](http://nltk.download)`('omw-1.4');` [`nltk.download`](http://nltk.download)`('wordnet')`: Download the WordNet corpus
    
* `COPY . .`: Copy all the files from the current directory to the Docker image
    
* `EXPOSE 5000`: Informs to use the port 5000
    
* `CMD ["flask", "run", "--host=0.0.0.0", "--port=5000"]` Run the Flask application
    

### 🐙 Docker Compose

Create a file called `docker-compose.yml` in the root directory. This file will contain the instructions to run the services (in this case just one).

```yaml
version:  "3.7"

services:
  mlapp:
    container_name: mlapp
    image: francescoxx/mlapp
    ports:
      - "5000:5000"
    build:
      context: .
      dockerfile: Dockerfile
```

Explanation of the `docker-compose.yml`:

* `version: "3.7"`: Use the version 3.7 of the Docker Compose file format
    
* `services:`: The services to run (in this case just one)
    
* `mlapp:`: The name of the service
    
* `container_name: mlapp`: The name of the container. It doesn't have to be the same as the service name but it's convenient.
    
* `image: francescoxx/mlapp`: The name of the image to use. ⚠️ replace `francescoxx` with your dockerhub username or change the name here
    
* `ports:`: The ports to expose
    
* `build:`: The instructions to build the image: the context (the current directory) and the Dockerfile to use
    

### 🏃‍♂️ Build and run the application

To run the application, you can use the following command:

```plaintext
docker compose up
```

Note: in case you get an error and you want to run this command again, you can use `docker compose up --build` to rebuild the image.

If you see something like this, it means that the application is running:

[![Flask app running with docker compose](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fd2k4jbcfc10tywa4kqp.png align="left")](https://youtu.be/zGP_nYmZd9c)

## 🔍 Test the application

This application is a simple Flask application that returns the sentiment of a text. Let's test if that works with Postman.

We will make 2 simple test with:

* positive text 👍
    
* negative text 👎
    

### Test 1

Make a `POST` request to [`http://localhost:5000/predict`](http://localhost:5000/predict) with the following body (be sure to have as a header `Content-Type: application/json`):

[![ImagPostman request](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9vzhcrjhieovfl2fygu9.png align="left")](https://youtu.be/zGP_nYmZd9c)

```json
{
    "text": "May the force be with you"
}
```

You should get the following response:

[![Postman response](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j4y5noy5fbrggj3z9znn.png align="left")](https://youtu.be/zGP_nYmZd9c)

### Test 2

Make a `POST request` to [`http://localhost:5000/predict`](http://localhost:5000/predict) with the following body (be sure to have as a header `Content-Type: application/json`):

```json
{
    "text": "I hate you"
}
```

[![Postman request](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sz5t11b8hkyxfz375q56.png align="left")](https://youtu.be/zGP_nYmZd9c)

This does work. You can also check the logs of the container to see what's happening:

[![docker compose logs](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z0bxajy9zlzc7rywtnxw.png align="left")](https://youtu.be/zGP_nYmZd9c)

## 💿 Push the image to Docker Hub

Last thing we can do is to push the image on Dockerhub. To do that, you need to create an account on Docker Hub. Then, you can push the image with the following command:

⚠️ replace `francescoxx` in the docker-compose.yml file with your Docker Hub username!

```plaintext
docker compose push
```

This will take a while, but after that, you can check your Docker Hub account and you should see the image there:

[![Docker Hub image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fqqhkyi2em0uojwlblbh.png align="left")](https://youtu.be/zGP_nYmZd9c)

## 🏁 Conclusion

In this tutorial, we have seen how to:

* create a Docker image for a Python application
    
* run the application with Docker Compose
    
* push the image on Docker Hub.
    

You can check the 2 videos below for a video version:

<iframe width="560" height="315" src="https://www.youtube.com/embed/zGP_nYmZd9c"></iframe>

First video by Patrick Loeber!

<iframe width="560" height="315" src="https://www.youtube.com/embed/S--SD4QbGps"></iframe>

That's all.

If you have any questions, drop a comment below.

[Francesco](https://francescociulla.com)
