Seamless Deployment of Django: Unlocking Efficiency with Gunicorn, Nginx, PostgreSQL, and Ubuntu - Part 1

Seamless Deployment of Django: Unlocking Efficiency with Gunicorn, Nginx, PostgreSQL, and Ubuntu - Part 1

Recently, I deployed a full-stack Django application on a Ubuntu server.

During the deployment process, I faced some issues in configuring everything on a production-ready server, mostly in configuring NGINX. I encountered the common error ‘502 Bad Gateway error. Today, I'm writing the step-by-step process of deployment and writing the issue I faced during the time and how I solved those.

Before jumping into the deployment part, I want to ensure you know the basics of the servers, especially the application server and web server, how they work, and why we need both to be up and running a fully functional web application.

Basic of Server

At a basic level, a server refers to a computer or system that serves the client's requested resources or services over a network. In the context of web applications, there are many kinds of servers. We will discuss its two types (web server and application server) and operations for our application deployment.

Web Server

It serves static content such as HTML, CSS, JavaScript, images, and files to the client when they request it. Its primary function is to receive HTTP requests from clients (web browsers) and respond with the requested resources.

Application Server

It is responsible for executing the application logic and processing dynamic content. It provides an environment to run server-side applications and handles dynamic requests by generating the necessary response.

I used NGINX as a Web Server and Gunicorn as an Application server in my project.

No alt text provided for this image

The basic flow of how the web server (nginx) and application server (Gunicorn) work

Now look into the complete step-by-step process of how the webserver (NGINX) and application server (GUNICORN) works in the context of the Django application.

But, before jumping into this, let's clarify the concept of Reverse Proxy. Nginx works as a reverse proxy. What is a reverse proxy?

A reverse proxy operates on behalf of the server, receiving requests from clients and forwarding them to the appropriate backend server. Nginx is referred to as a reverse proxy because it acts as an intermediary server between clients (such as web browsers) and backend servers (such as application servers).

Workflow

Let's jump into how the web server (Nginx) and application server (gunicorn) work. If I describe the process, the steps in the workflow would be as follows.

  1. The client (web browser) sends an HTTP request to the Nginx web server.

  2. Nginx, acting as a reverse proxy server, receives the request.

  3. Nginx checks if the request is for static content or dynamic content.

  4. If the request is for static content (e.g., HTML, CSS, images), Nginx directly returns the requested resource to the client.

  5. If the request is for dynamic content (e.g., Django views, database queries), Nginx forwards it to Gunicorn.

  6. Gunicorn, the Django application server, receives the request from Nginx.

  7. Gunicorn, running the Django application, processes the request by executing the necessary Python code (views, models, etc.), interacting with the database if required, and generating a response.

  8. Gunicorn sends the response back to Nginx.

  9. Nginx, acting as a reverse proxy, receives the response from Gunicorn.

  10. Nginx delivers the response back to the client (web browser).

  11. The client receives the response and displays the content or performs any required actions based on the received data.

The equivalent diagram of the process will be like this -

No alt text provided for this image

Details workflow of nginx and gunicorn

In this setup, Nginx acts as a reverse proxy, handling the initial request and deciding whether it should be served statically or passed to Gunicorn for dynamic processing. Gunicorn, as the Django application server, executes the Django application and generates dynamic responses. The division of responsibilities between Nginx and Gunicorn allows for efficient and scalable handling of web requests, leveraging Nginx's capabilities as a high-performance web server and Gunicorn's role as a reliable application server for Django.

In the next part of this article, we will configure the NGINX and Gunicorn to make our application up and running.

Reference

  1. EP 7 - Proxy, WebFlux, and SAGA Pattern.

  2. Why is Nginx called a “reverse” proxy? | by Ayush Soni | Mar, 2023 ....

  3. A tour of Django server setups