DEV Community

Christian Barra
Christian Barra

Posted on • Updated on • Originally published at pybootcamp.com

How to containerize a Python Application

Containers are everywhere, but how do you run a Python application inside a Docker container? This article will show you how!

In case you are wondering, the examples require Python 3.x.

Before diving into containers, let’s talk a bit more about the Python application we want to containerize.

The application is a web API that returns a random movie from a movie collection. Inside our local folder we have 3 files:

app.py # Python application
movies.json # movie collection
requirements.txt # where we specifiy our Python dependencies
Enter fullscreen mode Exit fullscreen mode

app.py contains one API endpoint that returns a random movie:

import os
import json
from pathlib import Path
from random import choice
import cherrypy

PORT = os.environ.get('PORT', 8888)

FOLDER_PATH = Path(__file__).parent

with open(FOLDER_PATH / "movies.json", "r") as f:
    MOVIES = json.loads(f.read())

class Movie:
    @cherrypy.expose
    @cherrypy.tools.json_out()
    def index(self):
        return {"movie": choice(MOVIES)}

cherrypy.quickstart(
    Movie(), config=cherrypy.config.update({
        'server.socket_host': '0.0.0.0',
        'server.socket_port': PORT,
        }))
Enter fullscreen mode Exit fullscreen mode

Inside requirements.txt, we have our dependencies and after running

pip install -r requirements.txt
Enter fullscreen mode Exit fullscreen mode

we are able to run our application with python app.py.

Running curl localhost:8888 should return a random movie, something like:

{
  "movie": {
    "Title": "Opal Dreams",
    "US_Gross": 14443,
    "Worldwide_Gross": 14443,
    "US_DVD_Sales": null,
    "Production_Budget": 9000000,
    "Release_Date": "Nov 22 2006",
    "MPAA_Rating": "PG",
    "Running_Time_min": null,
    "Distributor": "Strand",
    "Source": "Based on Book/Short Story",
    "Major_Genre": "Drama",
    "Creative_Type": "Contemporary Fiction",
    "Director": null,
    "Rotten_Tomatoes_Rating": null,
    "IMDB_Rating": 6.5,
    "IMDB_Votes": 468
  }
}
Enter fullscreen mode Exit fullscreen mode

Cool, the application is working!

How do we containerize our application?

Containerizing a Python application means creating a Docker image that has everything needed to run it: source code, dependencies and configuration..

The first step to containerize our application is to create a new text file, named Dockerfile:

app.py
movies.json
requirements.txt
Dockerfile
Enter fullscreen mode Exit fullscreen mode

Inside the Dockerfile (for what we consider a minimal viable Dockerfile), we need to specify three steps:

  • Select the base image we want to use
  • Select the files we want to copy inside the Docker image
  • Install the app's dependencies

Base image

To specify a base image, we use the FROM command followed by either a private or public image.

In our case, we will use the official Python Docker image, available on the Docker hub.

We will select the latest available Python 3 image based on Ubuntu.

# 1. Base image
FROM python:3.8.5-slim-buster
Enter fullscreen mode Exit fullscreen mode

The image name is made up of two different parts: image:tag. In our case the image is python and the tag is 3.8.5-slim-buster.

That's everything we need for the first step.

Copy our application

To copy our application inside the Docker image, we will use the COPY command:

# 2. Copy files
COPY . /src
Enter fullscreen mode Exit fullscreen mode

This command copies the specified files (or folder) into the Docker image. In our case, we want to copy all files available in our local folder inside the Docker image under the /src path.

It's important to note that the first part of the COPY command is a path relative to the context of the build and not to our local machine.

Install the requirements.txt

The last step is to install our dependencies inside the Docker image. To achieve that we will use the RUN command to RUN pip install:

# 3. Install our deps
RUN pip install -r /src/requirements.txt
Enter fullscreen mode Exit fullscreen mode

One thing to notice is that the path of requirements.txt is different compared with the first time we ran pip install.

The reason behind this is that the copied files are under the /src path inside the image.

Build and run a Docker image

# 1. Base image
FROM python:3.8.3-slim-buster

# 2. Copy files
COPY . /src

# 3. Install our deps
RUN pip install -r /src/requirements.txt
Enter fullscreen mode Exit fullscreen mode

Our Dockerfile is now complete and we can use it to build a Docker image. For that we need to use the docker build command:

docker build -t movie-recommender .
Enter fullscreen mode Exit fullscreen mode

This command builds a Docker image named movie-recommender using your current folder as building context (the . at the end specifies the path of the building context we want to use).

Now we can run the image we just built using the docker run command:

docker run movie-recommender python /src/app.py
Enter fullscreen mode Exit fullscreen mode

This command will execute python /src/app.py inside a container based on the movie-recommender image.

However, if we try to connect to our application using curl localhost:8888, we will get an error.

How is that possible? Why can't we connect to our application that runs inside the container?

The reason is that we didn’t expose our application's port to the local machine. We can do that by using the -p HostPort:ContainerPort flag.

So let’s try to rerun the command again, this time specifying that we want to expose port 8888 locally:

docker run -p 8888:8888 movie-recommender python /src/app.py
Enter fullscreen mode Exit fullscreen mode

and then curl localhost:8888.

Now it works—great! We just containerized a Python application!

Quick recap

  • Containerizing an application means to create a Docker image that has everything needed to run it—source code, libraries, and configuration.
  • We used a Dockerfile to specify how to build a Docker image.
  • docker build builds a Docker image starting from a Dockerfile.
  • docker run runs a container using a Docker image.

Useful resources

Discussion (0)