How to containerize a Flask Python application using Docker

How to containerize a Flask Python application using Docker

Before Docker, developers, and operations engineers had a huge setback when deploying an application to the servers because dependencies were to be installed on every machine to run the desired application. This approach created a lot of errors and misunderstandings.

Docker came in to solve this problem by containerizing the application to a single image which incorporates all its dependencies and configurations thus reducing errors and the amount of work and expertise to install on different machines. Images can run smoothly regardless of your operating system, it is lightweight since it can be scaled up or down and containers can be easily managed and automated.

Pre-requisites

Docker Installed and running.

Basic understanding of Python and Docker concepts

Visual Studio Code

Bash terminal

Setting up the Python application

In this project, you will design a Python application using the Flask framework to handle HTTP requests. It’s a framework used to create web applications and has built-in features in development servers.

Project Files

In this tutorial, I will show and guide you on how to create a simple Flask app that will include the following:

  • A basic structure for the Flask application

  • A route that handles GET requests and returns a simple response.

  • Running the Python Flask app on the terminal by using Python commands.

Follow these steps to design the application.

Set up an ideal environment

  • Make sure you have the latest Python and Flask installed.

  • Create a new directory for your Flask app.

  • Navigate to that directory in your terminal.

Create and activate a virtual environment

python -m venv venv

On windows, use venv\Scripts\activate

source venv/bin/activate

Install Flask

Run this command in your terminal

pip install Flask

Create a Flask app

In your project directory, create a new file and call it web.py

In web.py, import Flask and create an instance of the Flask application.

Define a route that listens to GET requests on the root URL ‘/’ and returns a simple message.

Your code should look like this;

from flask import Flask

# Create an instance of the Flask application
web = Flask(name)

# Define a route for the root URL ("/")
@web.route('/')

def index():
return 'Hello DevOps Engineer, This is your Python Flask App. Congratulations!'

# Run the application
if name = 'main':
web.run(host="0.0.0.0", port=int("3000"), debug=True)

In the above code snippet;

You import the Flask class and create an instance of the Flask application named web.

The route decorator @web.route(‘/’) specifies that the function index() returns a simple message: “Hello, DevOps Engineer. This is your Python Flask App. Congratulations!

The web.run() method starts the application whereas debug=True enables debugging mode.

Run the app

For the app to run, execute the following command in your terminal.

python web.py

On the terminal, you should see an output indicating that your Flask app is running and how to access it via this link URL.

Navigate to your browser with the specified URL and see your Flask app in action.

Dockerfile

A Dockerfile is a text document that encompasses all the commands a developer will call on the command line for it to build an image. It consists of the base image of your app, the directory of your app, the dependencies document, the environment that can also be specified, the port for your app, and relevant commands to run the image after building.

How to create a Dockerfile.

Since the Server is running, stop the server by pressing Ctrl + C on your keyboard.

Navigate to the home directory and create a Dockerfile by running the following command;

touch Dockerfile

After the successful creation of the Dockerfile, the next step is creating commands for them to build an image.

Creating Dockerfile Instructions for the Python application

The Dockerfile have the following commands:

# Use the official Python image as a base
FROM python

# Set the working directory in the container
WORKDIR /app

# Copy the requirements.txt file to the working directory
COPY . /app

# Install the required dependencies
RUN pip install -r requirements.txt

EXPOSE 3000

# Define the command to run the app and expose the port the app runs on
CMD python ./web.py

Explanation of each Dockerfile instruction

FROM python

Use the official Python base image. Not specifying the Python image, it will automatically use the latest Python-based image.

WORKDIR /app

Sets the working directory to /app.

COPY . /app

This command copies all files from the current directory (Dockerfile location) to the /app directory in the container.

RUN pip install -r requirements.txt

This command will install the dependencies specified in the requirements.txt and ensure all required packages are installed.

EXPOSE 3000

This command exposes port 3000

CMD python ./web.py

This command defines the command to run the Flask app.

Since there is no file named requirements.txt, it can be created easily by the command pip freeze which lists all the dependencies of the image. To store the dependencies on a file you have to specify the text file running this command on your terminal.

pip freeze > requirements.txt

Building the Docker image

Now, after the Dockerfile is set and no typo errors, create an image by running this command on your terminal:

docker build -t <username:version> 

docker build is a docker command to build the image.

-t will tag the image.

username is your docker registry username plus your desired container name separated by a forward slash.

version can be expressed in different styles e.g. v1.0.0, 0.0.1 RELEASE among others.

Assume my command to build my container was this;

docker build -t joshmurih/webapp:0.0 .

Running the Container

After successfully creating a Docker image, it is necessary to run the container to check for errors and make sure that it works as expected so that the container can later be pushed to the Docker hub for deployment.

Suitable commands to run the image

On the terminal run the following command:

docker container run -d -p 3000:3000 <username:version>

docker container run: This is a Docker command to run images.

-d means you run the image in “detach” mode. (You cannot be able to visit the site and test the docker image on your terminal).

-p 3000:3000: This command means that you are binding port 3000 to the docker default port.

<username:version> This will be the exact name you defined when creating the Docker image.

Testing the final containerized application

To verify the image is running in the background, run this command on your terminal.

docker container ls

It displays all the containers that are running. The current container is the first one.

Open your browser and visit this URL:

After successfully running the URL, you should see the data below otherwise repeat the process counter checking for minor typos and other errors.

Docker Hub

Docker Hub is a software platform built for developers to find, use, and share containers from anywhere on the continent.

For your team to use the final image you have already created, you have to push the container to Docker Hub for deployment and they in return will pull the final containerized application to their operating system for further use.

Pushing the docker image for deployment

Since you created the docker image with the tag of your Docker Hub username there is no need to tag it again.

Proceed to docker login and enter the required username and password when prompted.

Once logged in you can push your image to Docker Hub using the following command:

docker push <username:version>

Conclusion

Containerized applications run on isolated environments thus making it easier to manage dependencies and avoid conflicts between applications. Its portability and lightweight nature make deployment and testing easier. Since the containers share the host operating system’s kernel, utilisation of hardware resources creates efficiency. Lastly, the containers can be started and stopped quickly. This speed enables the developers to run new updates hence boosting the market of new features.