This guide covers deploying the Ticket Classification API to AWS using EC2 and ECS options.
- Prerequisites
- Option 1: EC2 Deployment
- Option 2: ECS with Fargate
- Security Configuration
- Monitoring & Logging
- AWS Account with appropriate permissions
- AWS CLI configured locally
- Docker installed for building images
- Trained model (run
python scripts/train.pyfirst)
# Install AWS CLI
pip install awscli
# Configure credentials
aws configure-
Go to EC2 Console → Launch Instance
-
Choose AMI: Amazon Linux 2023 or Ubuntu 22.04 LTS
-
Instance Type:
t3.small(minimum) ort3.medium(recommended)- 2 vCPU, 2-4 GB RAM for ML inference
-
Key Pair: Create or select existing key pair for SSH access
-
Network Settings:
- Allow SSH (port 22) from your IP
- Allow HTTP (port 80) from anywhere
- Allow Custom TCP (port 8000) from anywhere
-
Storage: 20 GB gp3 SSD minimum
# SSH into instance
ssh -i your-key.pem ec2-user@<public-ip>
# Update system
sudo yum update -y # Amazon Linux
# OR
sudo apt update && sudo apt upgrade -y # Ubuntu
# Install Docker
sudo yum install docker -y # Amazon Linux
# OR
sudo apt install docker.io -y # Ubuntu
# Start Docker
sudo systemctl start docker
sudo systemctl enable docker
sudo usermod -aG docker $USER
# Logout and login again for group changes
exit
ssh -i your-key.pem ec2-user@<public-ip># Clone repository
git clone https://github.com/yourusername/ticket-classifier.git
cd ticket-classifier
# Build Docker image
docker build -t ticket-classifier:latest .
# Run container
docker run -d \
--name ticket-api \
-p 8000:8000 \
--restart unless-stopped \
ticket-classifier:latest
# Verify deployment
curl http://localhost:8000/health# Install Nginx
sudo yum install nginx -y # Amazon Linux
# OR
sudo apt install nginx -y # Ubuntu
# Configure Nginx
sudo tee /etc/nginx/conf.d/ticket-api.conf << 'EOF'
server {
listen 80;
server_name _;
location / {
proxy_pass http://localhost:8000;
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_cache_bypass $http_upgrade;
}
}
EOF
# Start Nginx
sudo systemctl start nginx
sudo systemctl enable nginx# Create ECR repository
aws ecr create-repository --repository-name ticket-classifier --region us-east-1
# Get login command
aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin <account-id>.dkr.ecr.us-east-1.amazonaws.com
# Tag and push image
docker build -t ticket-classifier .
docker tag ticket-classifier:latest <account-id>.dkr.ecr.us-east-1.amazonaws.com/ticket-classifier:latest
docker push <account-id>.dkr.ecr.us-east-1.amazonaws.com/ticket-classifier:latest-
Go to ECS Console → Clusters → Create Cluster
-
Cluster name:
ticket-classifier-cluster -
Infrastructure: AWS Fargate (Serverless)
-
Click Create
-
Go to Task Definitions → Create new task definition
-
Task definition family:
ticket-classifier-task -
Launch type: AWS Fargate
-
CPU: 0.5 vCPU, Memory: 1 GB (minimum)
-
Container definitions:
- Name:
ticket-classifier - Image URI:
<account-id>.dkr.ecr.us-east-1.amazonaws.com/ticket-classifier:latest - Port mappings: 8000
- Name:
-
Go to Clusters → Select your cluster → Services → Create
-
Launch type: Fargate
-
Task definition: Select
ticket-classifier-task -
Service name:
ticket-classifier-service -
Desired tasks: 1 (or more for high availability)
-
Networking:
- VPC: Select default or your VPC
- Subnets: Select public subnets
- Security group: Allow port 8000
-
Load Balancer (optional but recommended):
- Application Load Balancer
- Health check path:
/health
| Type | Protocol | Port | Source | Description |
|---|---|---|---|---|
| SSH | TCP | 22 | Your IP | Admin access |
| HTTP | TCP | 80 | 0.0.0.0/0 | Public web |
| HTTPS | TCP | 443 | 0.0.0.0/0 | Secure web |
| Custom TCP | TCP | 8000 | 0.0.0.0/0 | API direct |
# Install Certbot
sudo yum install certbot python3-certbot-nginx -y
# Get certificate (replace with your domain)
sudo certbot --nginx -d api.yourdomain.com
# Auto-renewal
sudo certbot renew --dry-runFor sensitive configuration, use AWS Secrets Manager or SSM Parameter Store:
# Create secret
aws secretsmanager create-secret \
--name ticket-classifier/config \
--secret-string '{"API_KEY":"your-key","LOG_LEVEL":"info"}'Logs are automatically sent to CloudWatch when using ECS Fargate.
# View logs
aws logs get-log-events \
--log-group-name /ecs/ticket-classifier-task \
--log-stream-name <stream-name># Create CPU alarm
aws cloudwatch put-metric-alarm \
--alarm-name ticket-classifier-high-cpu \
--metric-name CPUUtilization \
--namespace AWS/ECS \
--statistic Average \
--period 300 \
--threshold 80 \
--comparison-operator GreaterThanThreshold \
--evaluation-periods 2# Simple health check script
#!/bin/bash
while true; do
response=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:8000/health)
if [ "$response" != "200" ]; then
echo "API unhealthy! Status: $response"
# Add alerting logic here
fi
sleep 60
done- Instance: ~$15/month
- Storage (20GB): ~$2/month
- Total: ~$17/month
- Compute: ~$15/month
- Storage: ~$2/month
- Load Balancer (optional): ~$16/month
- Total: ~$17-33/month
# EC2 Quick Deploy
ssh -i key.pem ec2-user@<ip>
git clone <repo> && cd ticket-classifier
docker build -t ticket-classifier .
docker run -d -p 8000:8000 ticket-classifier
# Test API
curl http://<public-ip>:8000/health
curl -X POST http://<public-ip>:8000/predict \
-H "Content-Type: application/json" \
-d '{"subject": "Test", "description": "This is a test ticket"}'