November, 2022

Quick & Easy Way to Deploy Web Application (Python) to Cloud Servers (AWS EC2 Instance)

SHARE THIS
“Sorry, we can’t process your request, the server is down.” Everyone must have heard this phrase at one time or the other, but what does it actually mean?

What the above phrase means is that at some point during routine work hours, there might come an occasion when a system receives bulk requests that it isn’t always capable of handling. So, the system (or the server) goes down…so to speak. It is on such occasions that we need resources capable of responding to bulk requests. But a traditional hosting system or VPS cannot perform that job for you.

Here lies the need for cloud infrastructure. Cloud infrastructure or cloud systems have a lot of extraordinary features that can support your application in a variety of ways. Numerous enterprise-level systems have already adopted the cloud for the provision of their services. While there are many reasons why you should consider migration to the cloud when it comes to enterprise solutions, I have listed a few of the major ones below.

Cloud Hosting

Is the cloud a machine where we put all our files or is it something like a gadget? It is neither. A cloud is not a single physical object. The cloud, as it is referred to, comprises multiple web servers that are connected by networks and are used to serve applications.
In the traditional hosting system, when a server fails, your application faces downtime. On the other hand, in the cloud, if one server fails, another is ready to serve your application. For large companies, server reliability is a major requirement. They want to ensure 24/7 availability of their application to the customers without even a minute of downtime.
VPS and traditional web servers may win in terms of cost but they will not be able to handle a large number of requests. Consequently, they are acceptable for startups where we don’t expect a high request rate in the beginning.
Although pricing is generally higher for cloud services, the cloud service providers usually offer pay-as-you-go services. So you don’t need to pay for services that you are not using, making the services easier on the budget for relatively smaller companies as well.
Other benefits include reduced risk of data loss because data is available on a remote location and has a continuous backup service and customizable capacity size.
There are a bunch of cloud services like GCLOUD (Google Cloud), Azure (Microsoft Cloud), and AWS (Amazon cloud services) which are available for the users, and each has its pros and cons. Below I have described how you can use AWS (Amazon Web services) EC2 instance to host your python website with a step-by-step guide.

 TOOLS

There are two major tools required to serve your application on production.

Web server
A web server is a tool used to handle requests from clients & send responses to clients against these requests. A web server is used to serve static content (HTML, image, audio, Video) on client request.
Example Apache, Nginx

Application server

An application server is used to apply business logic according to the client request and provide dynamic web content. Example Gunicorn. It is used to translate HTTP requests into something that python can understand.

Here, let me explain, how to deploy a python application from scratch on AWS EC2 instance using Supervisor, Nginx, and Gunicorn.

Supported versions:

    • Python => 3.8.
    • Django => 3.2
    • DRF => 3.11.
    • gunicorn==20.1.0

Prerequisites:

    EC2 instance (AWS)

Follow all the steps mentioned below to deploy your app on AWS.

STEP-1

EC2:
Ec2 (Amazon elastic compute cloud) is an instance of VM (virtual machine) which we can rent from AWS to deploy our application on the cloud. Due to the availability of a variety of OS images & resources, we can get customized instances, according to our desire. We don’t have to pay a fixed amount for that, it is a pay-as-you-go service. We can change the resources of our server anytime we require.

EC2 (Configuration/Setup):

  • Create your EC2 instance from EC2 Dashboard (make sure that the instance you are going to use for deployment should be in running state)
  • Download .pem and connect using SSH command with your instance (If you need any help in connection, check the how to connect instance guide from the EC2 dashboard.)
  • After logging into your instance, run these two commands

sudo apt update;
sudo apt upgrade –y;

These commands will help you to download and install all the latest updates of all outdated packages on your instance

  • As we are going to deploy a python application on our instance, we need PIP (Python Package Installer) & virtualenv (virtualenv helps us to deploy multiple projects with different requirements). Run the below command to install VENV and PIP.

sudo apt install python3-pip python3-venv

  • After installation of the above packages, create env (virtualenv) in your Django project directory.

python3 -m venv env

  • Activate your env (virtualenv)

. env/bin/activate
OR
source env/bin/activate

  • Install all your project requirements & gunicorn in the activated environment

Pip3 install gunicorn
Pip3 install –r requirements.

  • After completing the installation of your requirements, make a test run of your project by run server command (python manage.py runserver). It should start the development server. If the server has not started repeat all the above steps or check server logs.
  • In the end, just run your migrations.

Python manage.py makemigrations
Python manage.py migrate

STEP-2
GUNICORN:

Gunicorn is a WSGI (web server gateway interface) Application server that is used in communicating with web servers. As it is an application server it is used to create dynamic behavior in websites over the internet. It supports many frameworks and is popular due to its ease of use.

GUNICORN (configuration):

  • After installing Gunicorn in your env you need to activate the port that you want to use for your project. For enabling/activation of the port you need to add the port number into your security group by editing inbound rules. Follow the steps mentioned below to do that. I have added port 8000 because I will use this for the project.
1.

2.

3.
4.

  • After adding the port, go to the terminal and make a test run of your project with Gunicorn.

gunicorn –bind 0.0.0.0:8000 core.wsgi:application

Output of this command will be: 

  • Go to your browser and add this address http://serverip:8000 if it opens your application then you are on right track, otherwise repeat all the above steps and check where you have made the mistake. Afterward, close this by pressing command (ctrl + c) and your application will not run after terminating the process.

STEP-3

Supervisor:

As I mentioned in the above step, when you close the process, your application will stop working, but we don’t want that; we need our application to run 24/7 without any failure. So, we need something to ensure that our application is not stopped in case of any error or system reboot. We use process watchers for that purpose. Whenever the system reboots or any error occurs, our application will get started automatically by these tools. Supervisor is the perfect tool for that and hence why it is used here.

Supervisor (configuration):

  • Install supervisor by command

sudo apt install -y supervisor

  • Check Supervisor install by command sudo supervisorctl it will open up a supervisor console with no process listing.

  • Now we need to add a config file into supervisor. Go to path cd /etc/supervisor/conf.d/ create a file conf and open it by command sudo nano gunicorn.conf and add the below-mentioned content in that.

    [program:gunicorn]
    directory=/home/ubuntu/PROJECT_FOLDER
    command=/home/ubuntu/Path/env/bin/gunicorn –workers 3 –bind 0.0.0.0 DJANGO_PROJECT_FOLDER.wsgi:application
    autostart=true
    autorestart=true
    stderr_logfile=/home/ubuntu/logs/gunicorn.err.log
    stdout_logfile=/home/ubuntu/logs/gunicorn.out.log

  • Example File

  • After adding the file run all the below commands and check the output.

sudo supervisorctl reread

sudo supervisorctl update

sudo supervisorctl status

STEP-4

Nginx (engine-ex):

Nginx is an open-source web server, which is used to serve static files on servers. It is also used in load balancing, mail proxy, HTTP cache, WebSocket, and reverse proxy.

Nginx works on an event-driven approach to handle multiple requests concurrently while using low memory and without creating a new process for each request, this is what makes it extraordinary.

A paid version of Nginx, known as Nginx Plus, is also available for advanced usage.

Nginx (configurations):

  • Deactivate your env and install nginx globally by command sudo apt install nginx –y
  • After installation, open your browser and add the server IP. It will display the welcome to nginx page.
  • Now to add a configuration file, go to this path cd /etc/nginx/sites-available/ and create file sudo touch django.conf
  • Add the below configuration code in that file.

server {

    listen 80;

    server_name 0.0.0.0;

    location / {

        include proxy_params;

        proxy_pass http://localhost:8000;

    }
}

  • After adding the configuration file, run this command sudo ln django.conf /etc/nginx/sites-enabled/
  • Test Nginx configuration by command sudo nginx –t

  • After the successful test, restart nginx service by command sudo service nginx restart. Here you go. Now it is time to test our website. Go to the browser and add your server IP with PORT that you have added in nginx config file like in our case we add port 8000.
  • When you enter this address into the browser (ipaddress:8000) you will see your website running. If it displays any error check nginx error logs at cat /var/log/nginx/error.log
Picture of Ali Ahmad

Ali Ahmad

Ali, at TenX works as Software Engineer – Python