Pravesh Sudha

Deploying a Django App with Nginx: A Beginner's Guide

·

10 min read

Cover Image for Deploying a Django App with Nginx: A Beginner's Guide

đź’ˇ Introduction

In this blog, we are going to learn how to host a Django-based web application on an Nginx server. Nginx is a popular, high-performance web server used for serving static content and acting as a reverse proxy for dynamic applications. We will go over what Nginx is, how to install it, and how it works. By the end, you’ll have a Django app running on an Nginx server.

For this demonstration, we’ll be working on an Ubuntu-based EC2 instance, so if you’re using AWS, this will give you practical experience working with cloud infrastructure too.


đź’ˇ Pre-requisites

Before we jump into the project, here are a few things you need to know or have in place:

  • Basic Understanding of Linux: Familiarity with commands like cd, ls, and how to edit files using text editors like vim or nano.

  • EC2 Configuration: You should know how to create an EC2 instance, configure its security groups, and SSH into the instance.

  • Docker Installation: Since we’ll be using Docker to containerize our application, it needs to be installed on your EC2 instance. You can do this by running:

      sudo apt install docker.io
    
  • HTML Knowledge: A basic understanding of HTML will help when dealing with static content for our website.


đź’ˇ What is Nginx?

Nginx (pronounced "Engine-X") is a high-performance web server that also acts as a reverse proxy, load balancer, and HTTP cache. According to the official documentation:

"Nginx is an open-source software for web serving, reverse proxying, caching, load balancing, media streaming, and more."

It's widely used due to its ability to handle a lot of traffic with fewer resources.

Now, let’s break this down a bit. Imagine you’re organizing a concert. You have a lot of people coming in (like web requests), and you need someone (Nginx) to direct them efficiently—sending people to the correct seats (delivering web pages) or backstage (dynamic content) depending on what ticket (URL) they have. Apache2 or HTTPD are like older managers—still good but need more time and energy to handle the same amount of work.

Difference from Apache2, HTTPD: Nginx uses an event-driven architecture, while Apache2 uses a process-driven one. In simple terms, Nginx handles more requests at once without consuming a lot of resources because it doesn’t need to create a new process for every request. That’s why Nginx tends to be faster and more lightweight, especially for serving static content.

Nginx Architecture: Nginx operates with a master process and several child processes (called worker processes). The master process handles configuration, while the child processes actually serve client requests.

  • Master Process: Think of the master process as the main controller—it doesn’t deal with the actual work but tells the worker processes what to do.

  • Worker Processes: These are the ones that serve your requests. If you ask for a webpage, these processes will fetch it and send it to you.

  • Cache Manager and Cache Loader: These manage caching to ensure Nginx serves files quickly without pulling them from the server every time.

Nginx uses shared memory to store cached data, session permissions, logs, and even rate limits. This shared memory helps the child processes communicate and work together efficiently, ensuring everyone gets served as quickly as possible.


đź’ˇ Why Nginx and How it Works?

So, why are we using Nginx? Simple—it’s fast, efficient, and can handle a lot of traffic without breaking a sweat. Let’s talk about some of its cool features:

  • Reverse Proxy: This is one of Nginx’s biggest jobs. It stands in front of your web servers and forwards requests to them. Imagine a receptionist at a company—when you walk in and ask for someone, they direct you to the right person. Nginx is like that receptionist, sending requests to the right web servers based on load and availability.

  • Load Balancing: Nginx distributes incoming requests across multiple servers to ensure none of them get overwhelmed. If one server is down, Nginx reroutes the traffic to another. It’s like dividing work among group members in a project to ensure no one is overloaded.

  • Caching: Nginx saves copies of content so that the next time someone asks for the same thing, it can serve them faster without having to get the data again from the server. It’s like remembering an answer to a common question, so you don’t have to look it up every time.

  • URL Redirection: Need to send users from one URL to another? Nginx can do that too. It’s like telling someone, “Hey, that event has moved to a different room; follow me.”

  • Indexing: If you’ve ever navigated a folder on the web to see all the files listed, that’s indexing. Nginx can automatically create indexes of your directories, making file navigation easy.

How it Works: Let’s say you have multiple servers running different parts of a website (some for images, some for videos, and some for regular web pages). When a request comes in, Nginx decides which server can best handle it. If Server 1 is busy, it’ll forward the request to Server 2, and so on. This way, users get their content without delay. It’s like distributing incoming calls to customer service agents.


đź’ˇ Nginx Installation

Now that we’ve covered the basics, let’s get Nginx up and running on an Ubuntu-based EC2 instance.

  1. First, create a t2.micro instance on AWS and SSH into the server using your access key. (This step assumes you know how to set up an EC2 instance and access it via SSH).

  2. Once you're logged in, the first thing we want to do is update the server’s packages. Run this command:

     sudo apt update
    
  3. Now, let’s install Nginx with this command:

     sudo apt install nginx -y
    

  4. After installation, we can check if Nginx is running by using:

     sudo systemctl status nginx
    

You should see something that says active (running) if everything went well. Congrats, you’ve just installed Nginx on your server!

You can see the default “Welcome to Nginx“ page on the Public IP Address:


đź’ˇ How Nginx Works

Now that we have Nginx installed, let’s dive into how it works behind the scenes, starting with how it serves files and handles configurations.

When you install Nginx, it serves files from a default location, which is /var/www/html/. Any HTML file placed in this folder will be served by Nginx on your server’s IP address (or domain if you’ve set that up). This means if you create or move files into this directory, they will be accessible via your browser.

Nginx Configuration: The main configuration file for Nginx is located in /etc/nginx/ and is called nginx.conf. This file contains important settings that determine how Nginx behaves as a server, including things like the worker processes, logging, and connections. For now, don’t change anything in this file unless absolutely necessary.

Inside the /etc/nginx/ directory, you’ll also see two important folders:

  • sites-available: This is where you store configurations for websites or services that are not currently active but might be needed later.

  • sites-enabled: This folder contains the configurations that Nginx is currently using to serve your websites. Configurations from here are deployed and actively serving traffic.

In most cases, you’ll create your configurations in sites-available, and then symlink them to sites-enabled when you’re ready to deploy them.


đź’ˇ Hosting Your Resume Website

Before we get into deploying a Django application, let’s try hosting something simpler first—your resume website.

We’ll grab your code from your GitHub repository and set it up on Nginx. Here’s how:

  1. Clone the GitHub repository: First, SSH into your EC2 instance, then use the following command to clone your resume website’s repo:

     git clone https://github.com/Pravesh-Sudha/Resume-Website.git
    
  2. Move the necessary files: Once you have the repo, navigate to the folder and copy the index.html file into the /var/www/html/ folder. This will allow Nginx to serve your resume website:

     sudo cp Resume-Website/index.html /var/www/html/
    
  3. Update the file paths: In the index.html file, update the paths to make sure Nginx can find your styles and assets. Modify your HTML code like this:

     <link rel="stylesheet" href="/styles/main.css">
     <img id="profile-pic" src="/assets/images/profile_pic.jpg">
    
  4. Move the styles and assets: Now, we need to make sure Nginx knows where to find your stylesheets and images. Copy the styles and assets directories into the /var/www/ folder:

     sudo cp -r Resume-Website/styles /var/www/
     sudo cp -r Resume-Website/assets /var/www/
    
  5. Update the Nginx configuration: We need to tell Nginx where to find the styles and assets. Open the default configuration file located in /etc/nginx/sites-enabled/ and update the location blocks:

     location /styles/ {
         alias /var/www/styles/;
     }
    
     location /assets/ {
         alias /var/www/assets/;
     }
    
  6. Reload Nginx: After making these changes, you’ll need to reload Nginx to apply them:

     sudo systemctl reload nginx
    

Now, if you navigate to your server’s IP in a browser, you should see your resume website being served by Nginx!


đź’ˇ Deploy Django Application

Now, let’s deploy a Django notes app on our Nginx server using Docker. Since Docker is already installed, we need to ensure we can run it without using sudo all the time. To do that, we’ll add our user to the Docker group with this command:

sudo usermod -aG docker ubuntu

After adding your user to the Docker group, restart your EC2 instance with:

sudo reboot

Wait for 2-3 minutes to let your instance restart, then verify that Docker is running by checking the version:

docker --version

Clone the Django project: We’ll now grab the source code for the notes app from GitHub:

git clone https://github.com/Pravesh-Sudha/django-notes-app.git

Build the Docker image: Go into the project directory and build the Docker image using the Dockerfile that’s already provided:

docker build -t notes-app .

Run the Docker container: Now, let’s run the container to host the Django app. We’ll map port 8000 from the container to port 8000 on the EC2 instance:

docker run -d -p 8000:8000 notes-app:latest

To access the application, you need to open port 8000 for inbound traffic in your EC2 instance's security group. Once this is done, you can visit your instance’s public IP on port 8000 and see the notes app in action.

However, exposing port 8000 directly isn’t the best idea from a security standpoint. So, let’s use Nginx as a reverse proxy to protect the app.

Set up Nginx as a reverse proxy: First, close port 8000 in your security group to avoid direct access. Then, edit Nginx’s default configuration file in /etc/nginx/sites-enabled. We’ll change the location / block to forward traffic to our Django app running on port 8000:

proxy_pass http://127.0.0.1:8000;

Save the file and restart Nginx to apply the changes:

sudo systemctl restart nginx.service

Now, we’ll move the static files of the Django app’s frontend to the Nginx directory. Run the following commands:

cd django-notes-app/mynotes/build
sudo cp -r * /var/www/html

If you navigate to your instance’s public IP (without specifying a port), you should now see the TWS Notes Application running, with Nginx reverse proxying requests from port 80 to port 8000.

Enable API Proxy: You might notice that the notes don’t get saved yet. That’s because we need to proxy API requests as well. To do this, open the Nginx config again and add a new location block for /api:

location /api {
    proxy_pass http://127.0.0.1:8000/api;
}

The file /etc/nginx/sites-enabled/default looks like this:

Save the file and restart Nginx:

sudo systemctl restart nginx

Now, if you visit the site again, you should be able to create notes, and they will be saved in the database!


đź’ˇ Conclusion

In this blog, we’ve covered how to host a Django-based application on an Nginx server using Docker. We started by installing Nginx and Docker, then hosted a simple resume website to understand the basics. After that, we deployed a Django app, used Nginx as a reverse proxy, and configured it to handle static files and API requests. By the end of this, you should now have a fully functional notes app running on your EC2 instance with Nginx and Docker.

Deploying applications like this is crucial in the real world, especially when it comes to optimizing performance and security. Hopefully, this blog gives you a solid foundation to build on, and you can start experimenting with more advanced configurations! For more informative blog, Follow me on Hashnode, X(Twitter) and LinkedIn.

Till then, Happy Coding!!