Using a custom domain for Django app hosted on AWS EC2


We already know how to host a Django app for free on Amazon (AWS) EC2 instance with Gunicorn and Nginx. But we were accessing the application using public IP. IP addresses are hard to remember and are not user-friendly. 

Domain names are easy to remember and gives a unique identity to your web application or website. In this article, we will see how to use a custom domain purchased from GoDaddy to access our Django web application.


The public IP address assigned to our EC2 instance can be changed if we restart the instance. We need to have an IP address that does not change every time our EC2 instance restarts. Elastic IP comes to rescue here.



Associating an Elastic IP to EC2 instance:

In the left-hand side menu of your EC2 instance dashboard, click on Elastic IP link.

Click on the 'Allocate Elastic IP Address' button. 

elastic ip to ec2 instance


Check the radio button 'Amazon's pool of IPv4 addresses' on the next screen and proceed. You will be assigned a new Elastic IP.

Now select this IP address and associate this with your running EC2 instance. 

Once this IP address is associated with your EC2 instance, this will your public IP. You can access your application on this IP address now. (Refer this article to learn how to access your Django application using public IP).

Now we have a static IP address associated with our EC2 instance which will not change between instance restarts.



Using a custom domain to access the Django application:

First, go to your domain registrar's website and manage your DNS settings.

In the A record, update the Elastic IP obtained previously.

a record dns


Now go to your Nginx sites-available folder and in the respective file, update the server block.

Replace the YOUR-PUBLIC-IP we used with the domain name.


server {
    listen 80;
    server_name YOUR-PUBLIC-IP;

    # to avoid any error while fetching fevicon
    location = /favicon.ico { access_log off; log_not_found off; }

    location /static/ {
        root /home/ubuntu/helloworld;
    }

    location / {
        include proxy_params;
        # communicate via socket file created by Gunicorn
        proxy_pass http://unix:/home/ubuntu/helloworld/helloworld.sock;
    }
}


The third line will become

server_name example.com


Reload the Nginx server using the command

sudo service nginx reload



Update the settings.py file:

In your Django project's settings.py file, update the allowed hosts variable. In addition to public IP, add the domain name in the list.

ALLOWED_HOSTS = ["3.12.45.222", "example.com"]


Wait for 10-20 minutes to propagate the A record changes.

Go to your browser and access your Django app using the domain name.

accessing django app using domain



Host your Django App on PythonAnyWhere without any hassle.


AWS EC2 Vs PythonAnyWhere for hosting Django application


We have hosted Django applications on AWS EC2 as well as on PythonAnyWhere. Here is a brief comparison of both.


AWS EC2:

Offers pay-as-you-go compute capacity
This is a small service that provides resizable compute capacity
Free for 12 months (750 hours of CPU usage)
Can use a custom domain in free tier plan (Extra charges may apply)
SSH access available
- Browser-based SSH connection available
- The developer needs to set up everything from scratch. Intermediate level of expertise required
- Root level access available
- Can install and use whatever tool/software is required
- Highly scalable
- The developer needs to manage the webserver
- Pricing https://aws.amazon.com/ec2/pricing/
Create a free account 
Hosting the Django app on EC2


PythonAnyWhere:
- Offers fixed price shared hosting starting with $5 per month
- Small Paas (platform as a service) provider which supports only Python web apps
- Always free plan available. 100 CPU seconds per day. 512 MB space
- Can not use a custom domain. The app will be hosted on username.pythonanywhere.com
- SSH access available
- Browser-based terminals available
- The application setup is extremely easy.
- Root level access not available
- Apart from web hosting, Only MySQL, Postgres and schedule tasks support is provided
- Good for small to medium traffic apps
- The developer needs to take care of code
- Pricing https://www.pythonanywhere.com/pricing/
Create a free account
Hosting the Django app on PythonAnyWhere


If you want to add points, please comment below.



Hosting Django app for free on Amazon (AWS) EC2 with Gunicorn and Nginx

Recently I hosted a Django project on EC2 instance of AWS. Hosting on PythonAnyWhere is a cakewalk as compared to hosting on EC2 instance. Since I have gone through the process, I am sharing the step by step approach to host Django application on EC2 instance.


We will be hosting the Django App on Free Tier EC2 Instance (t2.micro) which gives us the 750 hours of CPU usage, which should be more than enough for a small scale website.

Django - 2.x
Python - 3.5
EC2 OS - Ubuntu

 

Content:

- EC2 Free Tier account creation and SSH
- Hello World Django App
- Gunicorn 
- Nginx


EC2 Free Tier account creation and SSH:

Amazon offers an EC2 instance with 750 hours of CPU usage for free for 12 months. You can start by creating an account. Instructions to create an account and starting the EC2 instance are pretty clear. 

I chose Ubuntu 16.04 AMI.

Once your instance is up and running, download the private key file and place the same in ~/.ssh/ directory of your personal system.

You can SSH into your EC2 instance from your terminal using the below command.

ssh -i ~/.ssh/aws_key.pem ubuntu@ec2-13-99-202-128.us-east-2.compute.amazonaws.com

Where  ec2-13-99-202-128.us-east-2.compute.amazonaws.com is your instance's public DNS. 

If you are not able to connect the instance using SSH, go to security groups and in the inbound tab, create a rule for SSH with port 22 enabled.

ssh rule in ec2 aws

If the problem persists, follow connection guidelines.



Hello World Django App:

Python3 is already installed on this instance. We need to install pip and other dev tools. Run below commands

sudo apt-get update && sudo apt-get upgrade
sudo apt-get install python3-pip


We will be working in a virtual environment hence we need to install the same.

pip install virtualenv


Create a virtual environment and activate it. Now create a Django project.

(venv) ubuntu:~$  django-admin startproject helloworld

Update the ALLOWED_HOSTS in settings.py file. For now, you can allow requests from all DNS or IPs but this is not safe. A much safer way would be to use the current public IP of the instance.

ALLOWED_HOSTS = ["13.99.202.218"]


Start the development server.

python manage.py runserver 0.0.0.0:8000


Now when you type IP your instance's public IP address with 8000 port in the browser, you should be able to see the Default home page of hello world Django project. 

But before that, you need to add a custom TCP rule to allow incoming traffic on port 8000.


Gunicorn:

The development server of the Django application is good for testing but is highly insecure and can not handle more than one request at a time. In short for the production environment, we have to move away from the development server.

Stop the development server running on port 8000.

In the virtual environment, install Gunicorn if not installed already.

Start the Gunicorn using the below command.

gunicorn --workers 3 --bind 0.0.0.0:8000 helloworld.wsgi:application

This will start the Gunicorn on the same interface on which the development server was started. You can again test the application from the browser using public IP and port.


Nginx:

To integrate Gunicorn with Nginx make below changes.

Create a file /etc/nginx/sites-available/helloworld and paste the below content in it.

server {
    listen 80;
    server_name YOUR-PUBLIC-IP;

    # to avoid any error while fetching fevicon
    location = /favicon.ico { access_log off; log_not_found off; }

    location /static/ {
        root /home/ubuntu/helloworld;
    }

    location / {
        include proxy_params;
        # communicate via socket file created by Gunicorn
        proxy_pass http://unix:/home/ubuntu/helloworld/helloworld.sock;
    }
}


Now create the soft link of this file in the sites-enabled directory.

sudo ln -s /etc/nginx/sites-available/helloworld /etc/nginx/sites-enabled


Restart the Gunicorn using the below command.

gunicorn --workers 3 --bind unix:/home/ubuntu/helloworld/helloworld.sock helloworld.wsgi:application


This will enable the Nginx and Gunicorn communication over a socket instead of a port, which is faster and more secure.


Now you can access the application by typing your public IP in the browser. Enjoy the free hosting for up to 12 months.

aws public ip access django app


You can host your app for free (or for $5 with custom DNS) on Pythonanywhere




SUBSCRIBE
Please subscribe to get the latest articles in your mailbox.


Recent Posts:






© 2017-2019 Python Circle   Contact Us   Advertise with Us