Nov. 22, 2024, 9:10 a.m.  |     182     1         0

Deploying A Django Application using Gunicorn, Supervisor and NGINX on AWS EC2

Introduction

In this guide, we'll delve into the process of deploying a Django application on an AWS EC2 instance, leveraging the power of Gunicorn, Supervisor, and Nginx. This combination offers a robust, scalable, and secure solution for hosting your Django web application.

Key Technologies and Their Roles

  • Django: The core python framework that powers our web application.
  • Gunicorn: A Python WSGI HTTP Server that efficiently handles HTTP requests and forwards them to our Django application.
  • Supervisor: This is a process supervisor that monitors and manages the Gunicorn processes, ensuring their availability and automatic restarts in the event that they go down or the server is restarted.
  • Nginx: This is a high-performance web server and reverse proxy that distributes traffic to our Gunicorn workers, it also handles static files, and can provide some security features.
  • AWS EC2: Provides the virtual server infrastructure where your application and its components will reside.

How The Technologies Work Together

  1. Client Request: A user's browser sends an HTTP request to the Nginx server.
  2. Nginx Receives Request: Nginx receives the request and forwards it to a Gunicorn worker process.
  3. Gunicorn Handles Request: The Gunicorn worker process handles the request, interacts with the Django application, and generates a HTTP response.
  4. Response to Client: The response is sent back to Nginx, which then forwards it to the client's browser.
  5. Supervisor Monitoring: Supervisor monitors the Gunicorn processes, restarting them if necessary to ensure continuous service.

Setting Up EC2 Instance

  1. Create a new account or log into an existing AWS account via the AWS Management Console.
  2. Under services search for and select EC2
  3. Click on instances and click on ‘Launch Instances’

  4. Enter Server name

  5. Select the Ubuntu AMI

  6. Select the t2.micro if you want to stay on the Free tier.

  7. Under Network Settings Allow SSH, HTTP and HTTPS

  8. On the Summary pane on the right, confirm your set up and click on launch instance.

    You should see a success banner after a successful launch.

     

Connecting Securely to the EC2 Instance

There are multiple ways (read this to learn how to connect via PuTTY) to connect to an EC2 instance however, to keep things simple we will use the Amazon EC2 Instance Connect method

  1. Navigate to EC2 > Instances > Select your instance > Click on Connect

  2. On the Connect to Instance page, click on connect

Update Ubuntu packages on the server

  1. Run the command sudo apt-get update 
  2. Run the command sudo apt-get upgrade 
  3. Confirm python installation python3 –version

 

Set up python virtual environment

  1. Download the virtualenv package: Run the command sudo apt-get install virtualenv
  2. Create a new virtual environment: Run the command virtualenv venv om
  3. Activate the virtual environment: source ./venv/bin/activate

 

Pull Django Application from GitHub

Let us assume we are deploying a portfolio site in my github repository.

  1. Clone Repository: Within the EC2 terminal run  git clone https://github.com/charlesu49/portfolio
  2. Install Dependencies: Use pip to install required packages: pip install -r requirements.txt

 

Install Gunicorn

Install Gunicorn: Run the command pip install gunicorn to install gunicorn

 

Install and configure Supervisor

  1. Install Supervisor: Run the command sudo apt-get install supervisor to install supervisor.
  2. Configure supervisor
    1. cd /etc/supervisor/conf.d/
    2. sudo touch gunicorn.conf/
    3. sudo nano gunicorn.conf

      [program:gunicorn]
      directory:/home/ubuntu/portfolio
      command=/home/ubuntu/venv/bin/gunicorn --workers 3 --bind unix:/home/ubuntu/portfolio/app.sock portfolio.wsgi:application
      autostart=true
      autorestart=true
      stderr_logfile=/var/log/gunicorn/gunicorn.err.log
      stdout_logfile=/var/log/gunicorn/gunicorn.out.log
      
      [group:guni]
      programs:gunicorn
    4. Save and close file (CTRL + O > Enter > CTRL + X)
  3. Create log directory: Run the command mkdir /var/log/gunicorn/ to create log directory
  4. Configure supervisor to read the configuration: sudo supervisorctl reread
  5. Start gunicorn in the background using supervisor: sudo supervisorctl update
  6. Check supervisor status: sudo supervisorctl status Ensure you see RUNNING as shown below:

 

Install and configure Nginx

  1. Install nginx: sudo apt-get install -y nginx
  2. Confirm installation: Open your browser and type in the IPV4 address of your instance and you should see the below page:

  3. Configure Nginx
    1. cd /etc/nginx/
    2.  sudo nano nginx.conf Change the user www-data to any other configured user with necessary permissions. For the purpose of this test we will be using root to avoid any permission issues (this is not advised in a production setting)
    3. cd /etc/nginx/sites-available/
    4. Create a config file for this projects: sudo nano portfolio.conf

      server {
          listen 80;
          server_name <public_ipv4_address> <domain name e.g: charlesudo.com>;
      
          location / {
              include proxy_params;
              proxy_pass http://unix:/home/ubuntu/portfolio/app.sock;
          }
      
          # Static files
          location /static/ {
              alias /home/ubuntu/portfolio/staticfiles/;
          }
      
          # Media files
          location /media/ {
              alias /home/ubuntu/portfolio/media/;
          }
      }
      
    5. Close and save file (CTRL + O > Enter > CTRL + X)
  4. Test that the config is fine: sudo nginx -t
  5. Enable our site: sudo ln portfolio.conf /etc/nginx/sites-enabled
  6. Restart the Nginx service: sudo service nginx restart

 

Testing Deployment

Open your browser and type in public IPV4 address of your EC2 instance or a domain name mapped to it and you should be able to access your website. If you make a change to your code and push to git hub you can pull the changes on your EC2 server and restart supervisor to see the update by running the command: sudo systemctl restart supervisor

 

Comments

Sign in to add to the conversation