Configure NGINX Container as Reverse Proxy for Dockerized Flask Application.

Swaroop Shinde
9 min readOct 12, 2022

--

πŸ”° Hello ! I’m back here to integrate two most commonly used technologies in DevOps i.e. NGINX and Flask.

πŸ”° Click Here to watch video Demonstration !

πŸ”° From the following article you will learn one of the easiest way to implement NGINX and Flask within Docker Container's. But before we get our hands dirty with the practical implementation. Let’s first understand few terminologies & get easy tasks done first.

β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€”

πŸ”Ή Since I’ve implemented Docker several times in past few projects so will be skipping the part to explain the Docker, still if you wish to know more about itΒ ! Then check out This Article where I’ve explained about docker Containers in DepthΒ !

πŸ”Ή Let’s understand more about Flask Framework .

β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€”

βœ… Understanding Flask :

✰ Flask is a micro web framework written in Python. It is classified as a microframework because it does not require particular tools or libraries. It has no database abstraction layer, form validation, or any other components where pre-existing third-party libraries provide common functions.

✰ In short Flask is a Python module that lets you develop web applications easily.

✰ Since we’re more focused on Nginx so we won’t go in depth with respect to Flask, still as a small demonstration, Here’s a simple example to use flask hosting web app.

πŸ”° Right now we’re in my local Red hat system within Virtual Box.

πŸ”° The above image is the syntax to write a Hello World flask application. As you can see :

  1. Imports the Flask class from the flask package. Flask is used to create instances of web applications.
  2. Initializes the app as an instance of Flask.
  3. Sets a function that responds to the index route, β€˜/’, and displays β€˜Welcome to the new world`
  4. Runs the app if the current script being executed is app.py.

Now if we save the file and come back to the prompt

πŸ”Ή There are two Files, app.py and requirements.txt.

πŸ”Ή Flask always reads app.py as the default file which contains the code, but we can anyways change the file name and then mention it as an argument while running flask app.

πŸ”Ή The requirements.txt file simply contains the dependencies that might be require while running this flask app.

πŸ”Ή Now to Run i.e. to start our flask web server, use command flask run and it will host the web page on port 5000 which is the default flask port number.

As you can see, as soon as I use flask run, the application is hosted on localhost:5000

β—Ό But there’s an issue, at this stage when you hit the IP, the logs can be seen in the command prompt.

β—Ό I hit the IP address 3 times so GET request was executed, but this app which is running in command prompt is dynamic i.e. you can’t do any other work using command prompt, obviously I can use one more different window over here but in case you’re using a CLI based OS like an EC2 instance from AWS, so we don’t have any GUI and practically this is not the way flask application are hosted.

β—Ό So for this let’s use Docker so we can launch the flask using detached feature of it.

β—Ό To understand more about Dockerfiles, I’ve created detailed blog on the same so click here to land on the article.

➸ We’ll be using python as base image because it will be relevant to flask and pip3 will be pre-installed.

➸ Next we’re creating a directory within which all the activities will be performed .

➸ Now we’re copying all the file from current location where Dockerfile is present to the working directory i.e. flaskapp which is inside container.

➸ Next we’re installing the dependencies using pip3.

➸ Lastly when we’ll run this docker image, it will run the CMD internally and the flask app will start running within the container.

πŸ”° Use docker build command to build the image and the execution will start :

πŸ”° As per the Dockerfile it is performing all the steps with respect to the sequence.

πŸ”° Initially it pulled python image and then later it was configured to be a Flask app ready container, Let’s run & test it :

πŸ”° We will run container in detached mode, the name is given for simplicity and port is intentionally binding to 4000 just to check if we’re getting response from the container at port 5000 . The process is started & can be seen using docker ps.

πŸ”° At port number 4000, the flask app is running.

πŸ”° Now the Nginx will come into play. Let’s understand what is Nginx and why we need it here.

β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€”

βœ… Understanding Nginx :

πŸ”Ή At a very high level Nginx, pronounced like β€œengine-ex”, is an open-source web server that, since its initial success as a web server, is now also used as a reverse proxy, HTTP cache, and load balancer.

πŸ”Ή If you’re familiar with Apache HTTPD web server, you can relate but Nginx provides some more features and one of them which we will be using will be reverse proxy.

β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€”

βœ…What is Reverse Proxy ?

✰ In simple words reverse proxy directs client requests to the appropriate backend server. It is a server that sits in front of web servers and forwards client (e.g. web browser) requests to those web servers.

✰ Consider it as a Load balancer, when we hit the DNS name of load balancer, it forwards the request to instances configured with it. Similarly to enable this feature in Nginx, we’ll have to modify the configuration file a bit.

✰ Nginx by default runs on port 80. We will be using Nginx within docker container, so lets do it :

✰ the Nginx process is started, Let’s see how the default web page looks like :

✰ Now our next step is to change the config file according to our need since we want to display flask app which is running on port 5000 instead of this Nginx web page.

✰ Right now we’re inside the Nginx container so we can check the config file :

β—Ό The Nginx acts as per the nginx.conf file which is at /etc/nginx directory and if you’ll open this file, it will contain all the default configurations with respect to the servers because of which it is displaying the Nginx web page.

β—Ό So since we have to change this file, if I’ll open & show you this file, there are lots of constrains and directives mentioned, so it will be a bit confusing to configure it as per our requirement :

β—Ό Knowing all lines is not required as far as this practical is concerned, we can use one docker facility over here which is volume mounting.

β—Ό We will create our own config file and then mount it with this location so the container can read the config file and respond as per the specification.

β—Ό So lets come out and delete this container for now :

πŸ”° Since we’ll be writing our own config file, so make sure that the file name and extension is correctly being matched.

πŸ”° The β€œevents” context is used to set global options that affect how Nginx handles connections at a general level. There can only be a single events context defined within the Nginx configuration.

πŸ”° worker_connections can be referred as how many request this Nginx server can handle simultaneously, for this docker container 1000 connection will led to crash but in this case Kubernetes can be used where horizontal pods scaling can be done so the CPU usage stays stable. I’ll be destroying the environment after the practical this won’t affect the performance as such.

πŸ”° Next comes is the http block, now http protocol can have n number of servers and their own standards. So this block can have multiple number of child constraints of servers within it. Server is nothing but the IP address config and how the server will responsd based upon the directives which will be mentioned in this server block.

πŸ”° First we have listen 80, means the server will be working on port 80, Next is the server name which as the name suggest it can be a domain name or an IP address, in our case since I’m working on local VM so I’ve specified IP of my machine and then below that location β€œ/” means by default if the URL path is not mentioned completely, then it will be proxy passed i.e. will be redirected to the port number where flask app is running on this local server i.e 192.168.1.5:4000

πŸ”° Let’s save the file and use docker volume mount feature to change the config file within the docker container.

πŸ”° we don’t have Nginx server running on port 80, now let’s use -v to bind the volume and start the container :

πŸ”° The container is launched successfully & now if we hit the IP address :

πŸ”° Reverse proxy is now forwarding the request to the flask app which is running within the container.

β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€”

πŸ”° So From the Above Article we saw how to Configure NGINX Container as Reverse Proxy for Dockerized Flask Application. If you Find This Interesting then Do Follow & Connect on Linkedin πŸ˜„.

THANK YOU !!

β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€” β€”

--

--

Swaroop Shinde

Hey There πŸ‘‹ If You’re A Tech & DevOps Enthusiast, Then You’re on the Right Medium Profile. Make sure you stay Connected & Don’t miss an Opportunity to Learn !