Deploying Django to AWS EC2 with RDS and S3
## Architecture Overview
- **EC2** — runs Django + Gunicorn + Nginx
- **RDS PostgreSQL** — managed database with automated backups
- **S3** — stores user-uploaded media files
- **CloudFront** (optional) — CDN for static and media files
## RDS Setup
```python
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': config('DB_NAME'),
'USER': config('DB_USER'),
'PASSWORD': config('DB_PASSWORD'),
'HOST': config('DB_HOST'), # RDS endpoint
'PORT': '5432',
'CONN_MAX_AGE': 60,
}
}
```
## S3 Media Storage with django-storages
```bash
pip install django-storages boto3
```
```python
# settings.py
DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
AWS_STORAGE_BUCKET_NAME = config('AWS_STORAGE_BUCKET_NAME')
AWS_S3_REGION_NAME = config('AWS_S3_REGION_NAME', default='ap-south-1')
AWS_DEFAULT_ACL = None
```
## EC2 User Data Script
```bash
#!/bin/bash
apt update && apt install -y docker.io docker-compose
systemctl enable docker
usermod -aG docker ubuntu
cd /opt/myapp
docker compose up -d
```
## Security Groups
- EC2: allow 80, 443 from 0.0.0.0/0; allow 22 from your IP only
- RDS: allow 5432 from EC2 security group only (never public)
- S3: use IAM roles on EC2, not access keys in code
## Cost Optimisation
Use Reserved Instances for EC2 (up to 72% saving), and RDS storage autoscaling to avoid over-provisioning.