Spaces:
Runtime error
Runtime error
AWS Deployment Guide - Complete Steps
Prerequisites
1. AWS Account Setup
- Create AWS account at https://aws.amazon.com
- Enable billing alerts
- Create IAM user with admin access (don't use root)
- Install AWS CLI:
aws configure
2. Local Requirements
- Git installed
- Docker installed (for testing containers)
- AWS CLI installed
- EB CLI installed:
pip install awsebcli
Step 1: Prepare Your Application
A. Create Production Requirements
# Already done - verify requirements.txt has:
# - psycopg2-binary (PostgreSQL)
# - gunicorn (WSGI server)
# - whitenoise (static files)
# - dj-database-url (DB config)
B. Create Dockerfile
FROM python:3.11-slim
# Set environment variables
ENV PYTHONUNBUFFERED=1 \
PYTHONDONTWRITEBYTECODE=1 \
PIP_NO_CACHE_DIR=1
# Install system dependencies
RUN apt-get update && apt-get install -y \
gcc \
postgresql-client \
&& rm -rf /var/lib/apt/lists/*
# Set work directory
WORKDIR /app
# Install Python dependencies
COPY requirements.txt .
RUN pip install --upgrade pip && \
pip install -r requirements.txt
# Copy project
COPY videocaller/ ./videocaller/
# Collect static files
WORKDIR /app/videocaller
RUN python manage.py collectstatic --no-input
# Run migrations and start server
CMD ["daphne", "-b", "0.0.0.0", "-p", "8000", "videocaller.asgi:application"]
C. Create .dockerignore
env/
venv/
*.pyc
__pycache__/
db.sqlite3
.env
.git/
.github/
*.md
build.sh
Step 2: AWS Services Setup
A. Create RDS PostgreSQL Database
Go to RDS Console
- Navigate to https://console.aws.amazon.com/rds
Create Database
Choose: PostgreSQL 15 Template: Free tier (or Production for real apps) Settings: - DB instance identifier: aimeet-db - Master username: postgres - Master password: [generate strong password] Instance configuration: - DB instance class: db.t3.micro (free tier) Storage: - Allocated storage: 20 GB - Storage autoscaling: Enable Connectivity: - VPC: Default - Public access: Yes (for now, restrict later) - VPC security group: Create new - Database port: 5432 Database authentication: - Password authentication Additional configuration: - Initial database name: aimeet - Automated backups: Enable (7 days retention)Note the endpoint (e.g.,
aimeet-db.xxxxx.us-east-1.rds.amazonaws.com)
B. Create ElastiCache Redis
Go to ElastiCache Console
- Navigate to https://console.aws.amazon.com/elasticache
Create Redis Cluster
Cluster mode: Disabled Engine: Redis 7.x Cluster info: - Name: aimeet-redis - Engine version: 7.0 - Port: 6379 - Node type: cache.t3.micro - Number of replicas: 0 (for dev/test) Subnet group: Default Security groups: Create new or use defaultNote the endpoint (e.g.,
aimeet-redis.xxxxx.cache.amazonaws.com:6379)
C. Create S3 Bucket (Already exists for recordings)
- Verify your S3 bucket from AGORA_STORAGE_BUCKET_NAME
- Set CORS policy if needed for uploads
D. Create Application Load Balancer (ALB)
Go to EC2 > Load Balancers
Create ALB
Type: Application Load Balancer Name: aimeet-alb Scheme: Internet-facing IP address type: IPv4 Network mapping: - VPC: Default - Availability Zones: Select 2+ zones Security groups: Create new - Name: aimeet-alb-sg - Inbound: HTTP (80), HTTPS (443) Listeners: - HTTP:80 → Forward to target group (create below) - HTTPS:443 → Forward to target group (needs SSL cert)Create Target Group
Type: Instances Name: aimeet-targets Protocol: HTTP Port: 8000 VPC: Default Health check: - Protocol: HTTP - Path: / - Interval: 30 seconds
E. Request SSL Certificate (ACM)
Go to Certificate Manager
- Region: Same as ALB
Request Certificate
Domain: yourdomain.com Validation: DNS (recommended) Add to DNS: - Copy CNAME records to your domain registrar - Wait for validation (~5-30 minutes)Attach to ALB
- Edit HTTPS:443 listener
- Select your certificate
Step 3: Deploy Application
Option A: Deploy with Elastic Beanstalk (Easiest)
A.1 Initialize EB
cd c:\dev\Django-VIdeocall-App
# Initialize
eb init
# Prompts:
# Region: us-east-1
# Application name: aimeet
# Platform: Docker
# SSH: Yes (generate keypair)
A.2 Create Environment
eb create production
# Environment name: aimeet-production
# DNS CNAME: aimeet (will be aimeet.us-east-1.elasticbeanstalk.com)
# Load balancer: Application
A.3 Configure Environment Variables
eb setenv \
DJANGO_SECRET_KEY="your-secret-key" \
DJANGO_DEBUG="false" \
DJANGO_ALLOWED_HOSTS="aimeet-production.us-east-1.elasticbeanstalk.com,yourdomain.com" \
DATABASE_URL="postgresql://postgres:password@aimeet-db.xxxxx.us-east-1.rds.amazonaws.com:5432/aimeet" \
REDIS_URL="redis://aimeet-redis.xxxxx.cache.amazonaws.com:6379/0" \
AWS_ACCESS_KEY_ID="your-key" \
AWS_SECRET_ACCESS_KEY="your-secret" \
AWS_STORAGE_BUCKET_NAME="your-bucket" \
AGORA_APP_ID="..." \
AGORA_APP_Certificate="..." \
ASSEMBLYAI_API_KEY="..." \
GOOGLE_API_KEY="..." \
QDRANT_URL="..." \
QDRANT_API_KEY="..." \
PUSHER_APP_ID="..." \
PUSHER_KEY="..." \
PUSHER_SECRET="..." \
PUSHER_CLUSTER="..."
A.4 Deploy
eb deploy
A.5 Run Migrations
eb ssh
cd /var/app/current/videocaller
python manage.py migrate
python manage.py createsuperuser
exit
Option B: Deploy with ECS Fargate (More scalable)
B.1 Build and Push Docker Image
# Build
docker build -t aimeet:latest .
# Tag for ECR
aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin YOUR_ACCOUNT_ID.dkr.ecr.us-east-1.amazonaws.com
# Create repository
aws ecr create-repository --repository-name aimeet --region us-east-1
# Tag and push
docker tag aimeet:latest YOUR_ACCOUNT_ID.dkr.ecr.us-east-1.amazonaws.com/aimeet:latest
docker push YOUR_ACCOUNT_ID.dkr.ecr.us-east-1.amazonaws.com/aimeet:latest
B.2 Create ECS Cluster
aws ecs create-cluster --cluster-name aimeet-cluster --region us-east-1
B.3 Create Task Definition
Create ecs-task-definition.json:
{
"family": "aimeet-task",
"networkMode": "awsvpc",
"requiresCompatibilities": ["FARGATE"],
"cpu": "512",
"memory": "1024",
"containerDefinitions": [
{
"name": "aimeet-web",
"image": "YOUR_ACCOUNT_ID.dkr.ecr.us-east-1.amazonaws.com/aimeet:latest",
"portMappings": [
{
"containerPort": 8000,
"protocol": "tcp"
}
],
"environment": [
{"name": "DJANGO_DEBUG", "value": "false"}
],
"secrets": [
{"name": "DJANGO_SECRET_KEY", "valueFrom": "arn:aws:secretsmanager:..."},
{"name": "DATABASE_URL", "valueFrom": "arn:aws:secretsmanager:..."}
],
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "/ecs/aimeet",
"awslogs-region": "us-east-1",
"awslogs-stream-prefix": "ecs"
}
}
}
]
}
Register:
aws ecs register-task-definition --cli-input-json file://ecs-task-definition.json
B.4 Create ECS Service
aws ecs create-service \
--cluster aimeet-cluster \
--service-name aimeet-service \
--task-definition aimeet-task \
--desired-count 2 \
--launch-type FARGATE \
--network-configuration "awsvpcConfiguration={subnets=[subnet-xxx,subnet-yyy],securityGroups=[sg-xxx],assignPublicIp=ENABLED}" \
--load-balancers "targetGroupArn=arn:aws:elasticloadbalancing:...,containerName=aimeet-web,containerPort=8000"
Option C: Deploy on EC2 (Manual, most control)
C.1 Launch EC2 Instance
AMI: Ubuntu 22.04 LTS
Instance type: t3.medium
Security group: Allow 22 (SSH), 8000 (Daphne), 80, 443
Key pair: Create/select for SSH
Storage: 30 GB
C.2 SSH and Setup
ssh -i your-key.pem ubuntu@your-ec2-ip
# Update system
sudo apt update && sudo apt upgrade -y
# Install dependencies
sudo apt install -y python3.11 python3.11-venv python3-pip git nginx postgresql-client redis-tools
# Clone repo
git clone https://github.com/prashantdubeypng/Aimeet.git
cd Aimeet
# Create virtual environment
python3.11 -m venv env
source env/bin/activate
# Install dependencies
pip install --upgrade pip
pip install -r requirements.txt
# Set environment variables
sudo nano /etc/environment
# Add all env vars
# Run migrations
cd videocaller
python manage.py migrate
python manage.py createsuperuser
python manage.py collectstatic --no-input
# Create systemd service
sudo nano /etc/systemd/system/aimeet.service
/etc/systemd/system/aimeet.service:
[Unit]
Description=AIMeet Daphne Service
After=network.target
[Service]
User=ubuntu
Group=ubuntu
WorkingDirectory=/home/ubuntu/Aimeet/videocaller
EnvironmentFile=/etc/environment
ExecStart=/home/ubuntu/Aimeet/env/bin/daphne -b 0.0.0.0 -p 8000 videocaller.asgi:application
Restart=always
[Install]
WantedBy=multi-user.target
# Start service
sudo systemctl daemon-reload
sudo systemctl enable aimeet
sudo systemctl start aimeet
# Configure Nginx
sudo nano /etc/nginx/sites-available/aimeet
/etc/nginx/sites-available/aimeet:
upstream django {
server 127.0.0.1:8000;
}
server {
listen 80;
server_name yourdomain.com;
location / {
proxy_pass http://django;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /static/ {
alias /home/ubuntu/Aimeet/videocaller/staticfiles/;
}
location /media/ {
alias /home/ubuntu/Aimeet/videocaller/media/;
}
}
# Enable site
sudo ln -s /etc/nginx/sites-available/aimeet /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl restart nginx
# Install SSL (Let's Encrypt)
sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d yourdomain.com
Step 4: Configure Domain (Route 53)
A. Create Hosted Zone
- Go to Route 53
- Create hosted zone:
yourdomain.com - Note the nameservers
B. Update Domain Registrar
- Go to your domain registrar (GoDaddy, Namecheap, etc.)
- Update nameservers to Route 53's NS records
C. Create DNS Records
Type: A
Name: @ (or blank)
Value: [ALB DNS or EC2 Elastic IP]
TTL: 300
Type: CNAME
Name: www
Value: yourdomain.com
TTL: 300
Step 5: Setup CloudWatch Monitoring
A. Enable CloudWatch Logs
# For EB
eb logs --cloudwatch-logs enable
# For ECS - already enabled in task definition
# For EC2 - install CloudWatch agent
wget https://s3.amazonaws.com/amazoncloudwatch-agent/ubuntu/amd64/latest/amazon-cloudwatch-agent.deb
sudo dpkg -i amazon-cloudwatch-agent.deb
B. Create Alarms
Metric: RDSCPUUtilization > 80%
Metric: ALBTargetResponseTime > 2s
Metric: EC2StatusCheckFailed
Action: Send SNS notification
Step 6: Setup Auto-Scaling (Optional)
For EB
eb scale 2 # Start with 2 instances
# Configure auto-scaling
eb config
# Set min instances: 2
# Set max instances: 10
# Scaling trigger: CPU > 70%
For ECS
aws application-autoscaling register-scalable-target \
--service-namespace ecs \
--scalable-dimension ecs:service:DesiredCount \
--resource-id service/aimeet-cluster/aimeet-service \
--min-capacity 2 \
--max-capacity 10
Step 7: Backup Strategy
A. RDS Automated Backups
- Already enabled (7-day retention)
- Take manual snapshots before major changes
B. S3 Versioning
aws s3api put-bucket-versioning \
--bucket your-bucket \
--versioning-configuration Status=Enabled
C. Database Snapshots
# Manual snapshot
aws rds create-db-snapshot \
--db-instance-identifier aimeet-db \
--db-snapshot-identifier aimeet-db-backup-$(date +%Y%m%d)
Step 8: Security Hardening
A. IAM Roles
- Create role for EC2/ECS with minimal permissions
- Don't use root credentials
B. Security Groups
RDS Security Group:
- Inbound: PostgreSQL (5432) from EC2/ECS security group only
Redis Security Group:
- Inbound: Redis (6379) from EC2/ECS security group only
EC2/ECS Security Group:
- Inbound: HTTP/HTTPS from ALB only
- Inbound: SSH from your IP only
ALB Security Group:
- Inbound: HTTP (80), HTTPS (443) from 0.0.0.0/0
C. Enable WAF (Optional)
Go to AWS WAF
Create Web ACL
Attach to ALB
Enable managed rule sets:
- AWS-AWSManagedRulesCommonRuleSet
- AWS-AWSManagedRulesKnownBadInputsRuleSet
Step 9: CI/CD with GitHub Actions
Already configured in .github/workflows/deploy.yml but update for AWS:
name: Deploy to AWS
on:
push:
branches: [master]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: us-east-1
- name: Deploy to Elastic Beanstalk
run: |
pip install awsebcli
eb deploy production --staged
Step 10: Cost Optimization
Development/Testing
RDS: db.t3.micro (Free tier eligible)
ElastiCache: cache.t3.micro
EC2: t3.small
Total: ~$50-70/month
Production (Low traffic)
RDS: db.t3.small with Multi-AZ
ElastiCache: cache.t3.small with replication
EC2/ECS: 2x t3.medium
ALB: ~$16/month
Total: ~$150-200/month
Cost Saving Tips
- Use Reserved Instances (save 30-60%)
- Enable RDS auto-scaling storage
- Use S3 Intelligent-Tiering
- Set CloudWatch alarms for billing
- Use Spot Instances for non-critical workloads
Troubleshooting
Database Connection Issues
# Test from EC2
telnet aimeet-db.xxxxx.rds.amazonaws.com 5432
# Check security groups
# Ensure EC2 security group is allowed in RDS inbound rules
Static Files Not Loading
# Ensure STATIC_ROOT is set
# Run collectstatic
python manage.py collectstatic --no-input
# Check Nginx config
# Verify WhiteNoise middleware order
WebSocket Connection Fails
# Ensure ALB supports WebSocket
# Check target group health
# Verify Daphne is running (not Gunicorn)
Final Checklist
- RDS database created and accessible
- Redis cluster running
- S3 bucket configured
- Application deployed (EB/ECS/EC2)
- Migrations run
- Superuser created
- SSL certificate installed
- Domain pointed to ALB/EC2
- Environment variables set
- CloudWatch monitoring enabled
- Backups configured
- Security groups hardened
- CI/CD pipeline tested
- Cost alerts set
Quick Deployment Commands
# Elastic Beanstalk (recommended for quick start)
eb init
eb create production
eb setenv [all env vars]
eb deploy
eb ssh
cd /var/app/current/videocaller
python manage.py migrate
python manage.py createsuperuser
# Access logs
eb logs
# Check status
eb status
# Terminate (be careful!)
eb terminate production
Estimated Setup Time:
- EB Deploy: 2-3 hours
- ECS Deploy: 4-6 hours
- EC2 Manual: 6-8 hours
Support Resources:
- AWS Documentation: https://docs.aws.amazon.com
- Elastic Beanstalk Guide: https://docs.aws.amazon.com/elasticbeanstalk
- Django Deployment: https://docs.djangoproject.com/en/4.1/howto/deployment/
Good luck with your AWS deployment! 🚀