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
- EC2 Free Tier account creation and SSH
- Hello World Django App
- Gunicorn
- Nginx
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.
If the problem persists, follow connection guidelines.
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.
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.
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.
You can host your app for free (or for $5 with custom DNS) on Pythonanywhere.