DEV Community

Cover image for Scaling Flask with Docker: Deploying a Portfolio Project with NGINX Load Balancing
Pravesh Sudha
Pravesh Sudha

Posted on

Scaling Flask with Docker: Deploying a Portfolio Project with NGINX Load Balancing

Learn how to containerize your Flask project, deploy multiple instances, and use NGINX to distribute traffic seamlessly

💡 Introduction

Welcome to the World of Exploration!

Today, we’re diving into an exciting experiment with NGINX as a load balancer to see how we can distribute traffic across multiple instances of an application. For those of you who are new here, I regularly create blogs around DevOps projects, experimenting with various tools and technologies. If you’re interested in deploying projects to the cloud, check out my recent blog on How to Deploy a Flask Project on AWS Elastic Beanstalk.

In this project, we’ll revisit the same Flask portfolio project and take it a step further. Here’s what we’ll be doing:

  • Create three Docker images of the project with minor changes (changing the navbar color) and name them v1, v2, and v3.
  • Use a Docker Compose file to run these three versions of the application on separate ports.
  • Install NGINX, modify its configuration file, and use it as a load balancer to evenly distribute traffic between these versions.

💡 Prerequisites

Before starting, ensure you have the following:

  • A basic understanding of Docker and Docker Compose.
  • Docker installed on your system. Install Docker
  • NGINX installed (steps provided below).

💡 What is NGINX and How Does it Work as a Load Balancer?

Before diving into the practical demo, let’s understand NGINX and its role as a load balancer.

In a nutshell, NGINX is a reverse proxy server that hosts web applications and handles HTTP requests. It can also act as a load balancer, distributing incoming traffic to multiple servers to:

  • Improve performance.
  • Optimize resource utilization.
  • Increase application reliability.

Common Load-Balancing Methods:

  • Round-robin: Distributes requests sequentially to each server in the group.
  • Least Connections: Routes traffic to the server with the fewest active connections.

NGINX offers additional features like caching, HTTPS proxying for security, and compression to reduce bandwidth usage. Its configurations are stored in the nginx.conf file located in /etc/nginx/.

Why NGINX Instead of Apache?

  • Faster and more lightweight.
  • Ideal for static files and high-performance web servers.
  • Simpler configuration.

Now that we have a basic understanding, let’s jump into the demonstration!


Step 1: Clone the Flask Portfolio Project

First, clone my GitHub repository containing the Flask portfolio project:

git clone https://github.com/Pravesh-Sudha/ebs-demo.git
Enter fullscreen mode Exit fullscreen mode

This project contains the code and a Dockerfile to build a Docker image of the portfolio project.


Step 2: Build the Docker Images

Navigate to the project directory and build the first Docker image:

docker build -t <your-dockerhub-username>/flask-portfolio-app:v1 .
Enter fullscreen mode Exit fullscreen mode

This will create a Docker image named flask-portfolio-app:v1. To create two more images with minor changes:

  • Open the static/style.css file and update the navbar background color.

Image description

  • Build the second image:
   docker build -t <your-dockerhub-username>/flask-portfolio-app:v2 .
Enter fullscreen mode Exit fullscreen mode
  • Update the navbar color again and build the third image:
   docker build -t <your-dockerhub-username>/flask-portfolio-app:v3 .
Enter fullscreen mode Exit fullscreen mode

Now you have three different versions of the application!

Image description


Step 3: Push the Images to Docker Hub

Log in to your Docker Hub account:

docker login
Enter fullscreen mode Exit fullscreen mode

Push all three images to your Docker Hub repository:

docker push <your-dockerhub-username>/flask-portfolio-app:v1
docker push <your-dockerhub-username>/flask-portfolio-app:v2
docker push <your-dockerhub-username>/flask-portfolio-app:v3
Enter fullscreen mode Exit fullscreen mode

Step 4: Run the Applications Using Docker Compose

The project directory includes a docker-compose.yaml file. Open it and update the image names to match your Docker Hub images (v1, v2, v3).

Image description

Start the containers with:

docker-compose up
Enter fullscreen mode Exit fullscreen mode

You’ll see all three versions of the application running on different ports (5000, 5001, 5002).

Image description

Image description

Image description


Step 5: Install and Configure NGINX

Install NGINX

  • On macOS:
  brew install nginx
Enter fullscreen mode Exit fullscreen mode
  • On Linux:
  sudo apt install nginx -y
Enter fullscreen mode Exit fullscreen mode

Configure NGINX for Load Balancing

Locate the nginx.conf file by running:

nginx -h
Enter fullscreen mode Exit fullscreen mode

Image description

Navigate to the configuration file’s location and replace its content with:

worker_processes 1;

events {
    worker_connections 1024;
}

http {
    include mime.types;

    # Define the upstream cluster of Flask servers
    upstream flask_cluster {
        server 127.0.0.1:5000;
        server 127.0.0.1:5001;
        server 127.0.0.1:5002;
    }

    server {
        listen 8080;
        server_name localhost;

        location / {
            proxy_pass http://flask_cluster;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Save the file and restart NGINX:

sudo service nginx restart
Enter fullscreen mode Exit fullscreen mode

Ensure your Docker containers are running, then visit http://localhost:8080. You’ll see traffic being distributed across the three application versions! Everytime you reload the page, you will see a different version.


💡 Conclusion

Congratulations! 🎉 You’ve successfully deployed a load-balanced Flask portfolio project using Docker containers and NGINX. Here's what we achieved:

  1. Built three versions of a Flask application.
  2. Containerized the applications and hosted them on different ports using Docker Compose.
  3. Configured NGINX as a load balancer to distribute traffic efficiently.

Feel free to experiment further by tweaking NGINX configurations or exploring advanced features like HTTPS proxying and custom load-balancing algorithms.

If you enjoyed this project, check out my other blogs for more DevOps experiments and tutorials. Let’s keep learning and building! 🚀


Happy Coding!

Top comments (0)