Deploying Django on Amazon EC2 (Elastic Compute Cloud) is one of the most reliable and scalable ways to host a Django application. Amazon EC2 provides flexible virtual servers (instances) that give you full control over your hosting environment — from operating system configuration to web server management.
This post will guide you through every step of deploying a Django application on AWS EC2 using Ubuntu Server, Gunicorn, and Nginx. By the end of this tutorial, you’ll have a production-ready Django project running on a secure, scalable EC2 instance.
1. What is AWS EC2?
Amazon EC2 (Elastic Compute Cloud) is a core service of AWS that provides virtual machines (called instances) to run your applications. These instances can be configured with any software stack, and you pay only for the resources you use.
Key Features of EC2
- Scalable: Easily resize instances as your app grows.
- Customizable: Choose the operating system, instance type, and storage.
- Secure: Configure firewalls and SSH access.
- Reliable: Backed by AWS’s global infrastructure.
For Django applications, EC2 gives you complete control — making it ideal for developers who want flexibility and performance.
2. Prerequisites
Before deploying your Django application, ensure you have the following:
- An AWS account (you can create one at https://aws.amazon.com).
- Your Django project ready for deployment.
- Basic knowledge of Linux commands.
- Git installed on your local machine.
- A PostgreSQL or MySQL database (optional if you’re not using SQLite).
3. Step 1: Launch an EC2 Instance
a. Log in to AWS Console
- Go to the EC2 Dashboard in the AWS Management Console.
- Click on Launch Instance.
b. Choose an Amazon Machine Image (AMI)
Select:
Ubuntu Server 22.04 LTS (64-bit)
Ubuntu is the most common and well-documented choice for Django deployments.
c. Choose Instance Type
Select a size according to your needs:
- t2.micro (Free tier eligible, good for testing)
- t3.medium or higher for production
d. Configure Security Group
A security group acts as a virtual firewall for your instance.
Allow the following inbound rules:
| Type | Protocol | Port Range | Source |
|---|---|---|---|
| SSH | TCP | 22 | Your IP |
| HTTP | TCP | 80 | 0.0.0.0/0 |
| HTTPS | TCP | 443 | 0.0.0.0/0 |
This ensures you can access your server via SSH and allow web traffic to your Django app.
e. Launch the Instance
- Create or select a key pair for SSH access.
- Launch the instance and wait for it to initialize.
4. Step 2: Connect to Your EC2 Instance
Once the instance is running, connect via SSH.
Find Public IP Address
In your EC2 dashboard, note the Public IPv4 address.
SSH into Instance
If your key pair is mykey.pem, connect using:
chmod 400 mykey.pem
ssh -i "mykey.pem" ubuntu@your-ec2-public-ip
You are now logged into your EC2 instance as the Ubuntu user.
5. Step 3: Update System Packages
Before installing anything, always update system packages.
sudo apt update
sudo apt upgrade -y
This ensures all dependencies are up-to-date and minimizes potential conflicts later.
6. Step 4: Install Required Dependencies
Next, install essential packages including Python, pip, venv, and Nginx.
sudo apt install python3-pip python3-venv nginx git -y
Explanation:
python3-pip: Python package installer.python3-venv: Virtual environment for isolating project dependencies.nginx: Web server and reverse proxy.git: To clone your project from GitHub or another repository.
7. Step 5: Clone Your Django Project
Clone your Django project from your Git repository.
cd /home/ubuntu
git clone https://github.com/yourusername/yourproject.git
cd yourproject
If you don’t have a Git repository, you can upload files manually using SCP or SFTP.
8. Step 6: Set Up Python Virtual Environment
Create a virtual environment for your Django project to isolate dependencies.
python3 -m venv venv
source venv/bin/activate
Now, your shell prompt should change to indicate the virtual environment is active.
Install your dependencies:
pip install -r requirements.txt
Make sure gunicorn and django are listed in your requirements file.
If not, install them manually:
pip install django gunicorn
9. Step 7: Configure Django for Production
Before starting the server, adjust your Django settings for production.
a. Disable Debug
In settings.py:
DEBUG = False
b. Configure Allowed Hosts
ALLOWED_HOSTS = ['your-ec2-public-ip', 'yourdomain.com']
c. Collect Static Files
Run:
python manage.py collectstatic
This gathers all static files into one directory for Nginx to serve efficiently.
10. Step 8: Set Up Gunicorn
Gunicorn (Green Unicorn) is a Python WSGI HTTP server that runs your Django application in production.
a. Test Gunicorn
From your project root, run:
gunicorn --bind 0.0.0.0:8000 yourproject.wsgi
You should see Gunicorn running.
Visit your EC2 Public IP followed by :8000 (e.g., http://18.222.11.23:8000) in your browser — your Django app should load.
Press Ctrl + C to stop Gunicorn.
b. Create Gunicorn Systemd Service
Create a Gunicorn service file:
sudo nano /etc/systemd/system/gunicorn.service
Add the following configuration:
[Unit]
Description=gunicorn daemon for Django project
After=network.target
[Service]
User=ubuntu
Group=www-data
WorkingDirectory=/home/ubuntu/yourproject
ExecStart=/home/ubuntu/yourproject/venv/bin/gunicorn --workers 3 --bind unix:/home/ubuntu/yourproject/yourproject.sock yourproject.wsgi:application
[Install]
WantedBy=multi-user.target
Enable and Start Gunicorn
sudo systemctl start gunicorn
sudo systemctl enable gunicorn
sudo systemctl status gunicorn
Gunicorn will now start automatically whenever the server boots.
11. Step 9: Configure Nginx
Now you’ll set up Nginx to act as a reverse proxy for Gunicorn.
This ensures better performance, caching, and static file handling.
a. Create Nginx Server Block
sudo nano /etc/nginx/sites-available/yourproject
Add this configuration:
server {
listen 80;
server_name yourdomain.com your-ec2-public-ip;
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
root /home/ubuntu/yourproject;
}
location /media/ {
root /home/ubuntu/yourproject;
}
location / {
include proxy_params;
proxy_pass http://unix:/home/ubuntu/yourproject/yourproject.sock;
}
}
b. Enable Nginx Configuration
sudo ln -s /etc/nginx/sites-available/yourproject /etc/nginx/sites-enabled
sudo nginx -t
sudo systemctl restart nginx
c. Adjust Firewall
If you have a firewall enabled:
sudo ufw allow 'Nginx Full'
Now your Django app is served via Nginx on port 80.
12. Step 10: Secure Your Application with SSL
Security is crucial for production. Let’s enable HTTPS using Let’s Encrypt.
Install Certbot
sudo apt install certbot python3-certbot-nginx -y
Generate SSL Certificate
sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com
Follow the prompts to obtain and install the certificate.
Automatic Renewal
Certificates expire every 90 days.
Set up automatic renewal:
sudo systemctl enable certbot.timer
sudo systemctl start certbot.timer
Your site now runs securely over HTTPS.
13. Step 11: Configure Gunicorn and Nginx for Auto-Start
Ensure both Gunicorn and Nginx start automatically on system reboot.
sudo systemctl enable nginx
sudo systemctl enable gunicorn
You can check their status:
sudo systemctl status nginx
sudo systemctl status gunicorn
If everything is active and running, your deployment is complete.
14. Step 12: Setting Up Domain Name
If you own a domain name, point it to your EC2 instance.
a. Get EC2 Public IP
Find it under the instance details in AWS Console.
b. Configure DNS
In your domain registrar (e.g., GoDaddy, Namecheap):
- Create an A record pointing your domain to the EC2 public IP.
Once DNS propagation completes, your Django app will be accessible via your custom domain.
15. Step 13: Using a PostgreSQL Database (Optional)
For better performance, use PostgreSQL instead of SQLite.
Install PostgreSQL
sudo apt install postgresql postgresql-contrib
Create Database and User
sudo -u postgres psql
CREATE DATABASE mydb;
CREATE USER myuser WITH PASSWORD 'mypassword';
ALTER ROLE myuser SET client_encoding TO 'utf8';
ALTER ROLE myuser SET default_transaction_isolation TO 'read committed';
ALTER ROLE myuser SET timezone TO 'UTC';
GRANT ALL PRIVILEGES ON DATABASE mydb TO myuser;
\q
Update Django Settings
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'mydb',
'USER': 'myuser',
'PASSWORD': 'mypassword',
'HOST': 'localhost',
'PORT': '5432',
}
}
Then run:
python manage.py migrate
16. Step 14: Monitoring and Maintenance
To keep your server running smoothly, monitor performance and logs regularly.
Check Logs
- Nginx logs:
sudo tail -f /var/log/nginx/error.log - Gunicorn logs:
sudo journalctl -u gunicorn
Regular Updates
Keep the system updated:
sudo apt update && sudo apt upgrade -y
Server Monitoring
Use tools like:
- htop – Monitor resource usage.
- fail2ban – Protect from SSH brute-force attacks.
- UptimeRobot – External uptime monitoring.
17. Step 15: Backup Strategy
Always maintain backups of:
- Database
- Media files
- Configuration files
You can use AWS services like S3 for backups:
aws s3 sync /home/ubuntu/yourproject/media s3://your-bucket-name/media-backup
Schedule backups using cron jobs for automated daily backups.
18. Troubleshooting Common Issues
a. Permission Denied (403 or 500)
Ensure your directories have correct permissions:
sudo chown -R ubuntu:www-data /home/ubuntu/yourproject
b. Nginx Fails to Start
Check syntax:
sudo nginx -t
Restart the service:
sudo systemctl restart nginx
c. Gunicorn Not Running
Restart Gunicorn:
sudo systemctl restart gunicorn
sudo systemctl status gunicorn
19. Final Directory Structure
Here’s what your project directory should look like after deployment:
/home/ubuntu/yourproject/
│
├── manage.py
├── venv/
├── yourproject/
│ ├── settings.py
│ ├── wsgi.py
│ ├── urls.py
│ └── __init__.py
├── static/
├── media/
├── gunicorn.sock
└── requirements.txt
This structure ensures a clean and maintainable setup.
20. Advantages of Using AWS EC2 for Django
- Full Control: You manage everything — from web server to database.
- Scalability: Easily increase instance size or add load balancers.
- Reliability: AWS offers excellent uptime and global coverage.
- Flexibility: Choose custom configurations, storage, and security settings.
While EC2 requires more setup effort than platforms like Heroku, it’s a powerful and cost-effective choice for long-term scalability.
Leave a Reply