💡 Introduction
Welcome to the world of DevOps and automation! If you’re exploring web servers, reverse proxies, or load balancers, you’ve probably come across Nginx (pronounced "Engine-X"). It is one of the most popular web servers in the industry, known for its speed, scalability, and reliability.
In this blog, we will cover:
What is Nginx?
Why is Nginx used?
How does it work?
Configuring Nginx as a load balancer for a Flask-based portfolio website.
By the end of this guide, you will have a solid understanding of Nginx fundamentals, setting a strong foundation for working with web servers in real-world projects.
💡 What is Nginx?
If you’re new to DevOps, you might be wondering: What exactly is Nginx?
According to its official documentation:
"Nginx is an HTTP web server, reverse proxy, content cache, load balancer, TCP/UDP proxy server, and mail proxy server."
That sounds like a lot, right? You might be wondering: What is a reverse proxy? What is a load balancer? Don’t worry—we’ll break it down step by step!
Simplifying Nginx
At its core, Nginx is a web server that allows us to host websites and web applications. But it also comes with additional functionalities like:
Reverse Proxy – Nginx can act as an intermediary between users and backend servers. It allows us to expose only specific ports to enhance security while hiding the actual application ports. This prevents hackers from directly targeting backend services.
Load Balancer – Nginx efficiently distributes incoming traffic among multiple servers, preventing overload. It supports different load-balancing algorithms such as:
* Round Robin – Distributes requests sequentially across all servers.
* IP Hash – Routes requests from the same client IP to the same server.
* Least Connections – Sends traffic to the server with the fewest active connections.
Why Use Nginx Instead of Apache?
You may have heard of Apache Tomcat and Apache Web Server—so why do we need Nginx?
The key difference lies in performance:
Nginx excels at serving static content and handling high traffic.
Apache is better for dynamic content and shared hosting.
This makes Nginx a great choice for handling high-performance applications.
How Does Nginx Work?
The way Nginx operates is controlled by a configuration file (nginx.conf). This file defines how requests are processedand where Nginx should route traffic.
By default, the nginx.conf file is located in:
/etc/nginx
/usr/local/nginx/conf
/usr/local/etc/nginx
This file is the heart of the web server—it manages all of Nginx’s operations.
To fully understand Nginx, we will configure it as a Load Balancer for a Flask-based portfolio website. We’ll create our own nginx.conf file from scratch, giving you a hands-on understanding of how Nginx works in real-world applications.
💡 Setting Up Nginx and Docker
Before we dive into configuring Nginx as a Load Balancer, we need to install Nginx and Docker on our system. These tools will allow us to:
Run our Flask-portfolio application inside Docker containers.
Configure Nginx to distribute traffic across multiple application instances using different load-balancing algorithms.
Installing Docker and Nginx
If you’re on Ubuntu, run the following commands:
sudo apt install docker.io nginx -y
sudo usermod -aG docker $USER && newgrp docker
For MacOS, use Homebrew to install both tools:
brew install docker nginx
Once installed, ensure Nginx is running by checking its version:
nginx -v
Configuring Nginx as a Load Balancer
Now, let’s create the nginx.conf file that will define how Nginx distributes traffic.
First, find the default location of the Nginx configuration file by running:
which nginx
This will give you a path like /etc/nginx/nginx.conf
(or a similar location).
Navigate to this directory and replace the contents of the existing nginx.conf
file with the following:
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;
}
}
}
Understanding the nginx.conf File
- worker_processes 1;
* Defines the number of worker processes handling requests. We set it to **1** for simplicity.
- events { worker_connections 1024; }
* Sets the maximum number of connections a worker can handle.
- http { include mime.types; }
* Includes MIME types for handling different file formats.
- upstream flask_cluster { ... }
* This defines a **load-balancing group** called `flask_cluster`, consisting of **three Flask servers** running on different ports:
* `127.0.0.1:5000`
* `127.0.0.1:5001`
* `127.0.0.1:5002`
- server { listen 8080; server_name localhost; }
* Configures Nginx to listen on **port 8080** and serve requests from [`localhost`](http://localhost).
- location / { proxy_pass http://flask_cluster; }
* Directs all incoming traffic to the **Flask application servers** defined in the `flask_cluster`.
* The `proxy_set_header` directives help preserve the original request headers.
Running Flask Containers in Docker
Now that Nginx is configured, let’s run our Flask-portfolio application inside Docker containers.
Run the following commands to start three instances of your Flask app, each on a different port:
docker run -d -p 5000:5000 pravesh2003/flflask-portfolio-app:v1
docker run -d -p 5001:5000 pravesh2003/flflask-portfolio-app:v2
docker run -d -p 5002:5000 pravesh2003/flflask-portfolio-app:v3
(Note: The typo in the Docker image name flflask-portfolio-app
is intentional, as it was pushed that way to Docker Hub.)
Testing the Load Balancer
Once the containers are running, go to your browser and visit:
http://localhost:8080
Each time you refresh the page, you’ll notice that the color of the navbar changes. This is because different versions of the Flask-portfolio app are being served, depending on how Nginx distributes the requests.
How Does This Work?
Flask applications normally run on port 5000.
Nginx acts as a reverse proxy, redirecting traffic from port 8080 to ports 5000, 5001, and 5002.
Users only interact with port 8080, ensuring that the application’s internal ports remain hidden for security reasons.
This is a good security practice because it prevents direct access to backend services, reducing the risk of cyber attacks.
💡 Conclusion
In this blog, we explored Nginx from the ground up—understanding what it is, why it's used, and how it works. We then took a hands-on approach by configuring Nginx as a Load Balancer for a Flask-portfolio application running inside Docker containers.
Key Takeaways:
✅ Nginx is a powerful web server that can act as a reverse proxy and load balancer.
✅ Reverse proxying helps in security by hiding application ports from direct exposure.
✅ Load balancing improves scalability by distributing traffic across multiple instances.
✅ Nginx configuration is controlled via nginx.conf, which defines traffic routing rules.
✅ Using Docker makes it easy to containerize and scale applications dynamically.
With this foundation, you can now experiment with different load-balancing algorithms, SSL termination, or even setting up Nginx as a caching server to optimize performance.
What’s Next?
Try modifying the nginx.conf
file to test different load-balancing algorithms such as Least Connections or IP Hash. You can also explore adding HTTPS with SSL certificates to make your application more secure.
Nginx is a must-have tool in any DevOps or Cloud Engineer’s toolkit, and mastering it will open doors to high-performance web hosting, traffic management, and scalable deployments.
Happy coding! 🚀
✨ For more informative blog, Follow me on Hashnode, X(Twitter) and LinkedIn.
Top comments (0)