aws-final-project/DEPLOYMENT.md
2025-12-17 00:15:27 +02:00

8.8 KiB

Deployment Guide

This guide covers deploying the dating app to different environments.

Local Development (Docker Compose)

Quick Start

cd aws-final-project

# Setup environment files
cp backend/.env.example backend/.env
cp frontend/.env.example frontend/.env

# Start services
docker-compose up -d

# Verify services are running
docker-compose ps

Access Points

Development Mode

For development with hot reload:

# Backend with reload
docker-compose up -d postgres
cd backend
python -m uvicorn main:app --reload

# Frontend with reload (in another terminal)
cd frontend
npm install
npm run dev

Cleanup

docker-compose down -v  # Remove volumes too

Kubernetes Deployment (Home-Lab)

Prerequisites

# Install Kubernetes (minikube, kubeadm, or managed)
# Install Helm
# Install Nginx Ingress Controller

Step 1: Build and Push Images

# Set your registry URL
REGISTRY=your-registry-url

# Build and push backend
docker build -t $REGISTRY/dating-app-backend:v1 backend/
docker push $REGISTRY/dating-app-backend:v1

# Build and push frontend
docker build -t $REGISTRY/dating-app-frontend:v1 frontend/
docker push $REGISTRY/dating-app-frontend:v1

Step 2: Update Helm Values

cp helm/dating-app/values-lab.yaml my-values.yaml

Edit my-values.yaml:

backend:
  image:
    repository: your-registry/dating-app-backend
    tag: v1

frontend:
  image:
    repository: your-registry/dating-app-frontend
    tag: v1

backend:
  ingress:
    host: api.your-lab-domain.local

frontend:
  ingress:
    host: app.your-lab-domain.local

Step 3: Deploy with Helm

helm install dating-app ./helm/dating-app \
  -n dating-app \
  --create-namespace \
  -f my-values.yaml

Step 4: Configure DNS (Optional)

For local access without DNS:

# Add to /etc/hosts (Linux/Mac) or C:\Windows\System32\drivers\etc\hosts (Windows)
<your-cluster-ip> api.your-lab-domain.local
<your-cluster-ip> app.your-lab-domain.local

Or use port forwarding:

kubectl port-forward -n dating-app svc/frontend 3000:80
kubectl port-forward -n dating-app svc/backend 8000:8000

Monitoring Deployment

# Watch pods
kubectl get pods -n dating-app -w

# Check events
kubectl get events -n dating-app --sort-by=.metadata.creationTimestamp

# View logs
kubectl logs -n dating-app deployment/backend
kubectl logs -n dating-app deployment/frontend

# Check ingress
kubectl get ingress -n dating-app
kubectl describe ingress -n dating-app

AWS EKS Deployment

Prerequisites

# AWS CLI configured
# kubectl installed
# helm installed
# AWS EKS cluster created
# RDS PostgreSQL instance running
# ECR repository created

Step 1: Build and Push to ECR

# Login to ECR
aws ecr get-login-password --region us-east-1 | \
  docker login --username AWS --password-stdin <account>.dkr.ecr.us-east-1.amazonaws.com

# Build and push
ACCOUNT=<your-account-id>
REGION=us-east-1

docker build -t $ACCOUNT.dkr.ecr.$REGION.amazonaws.com/dating-app-backend:v1 backend/
docker push $ACCOUNT.dkr.ecr.$REGION.amazonaws.com/dating-app-backend:v1

docker build -t $ACCOUNT.dkr.ecr.$REGION.amazonaws.com/dating-app-frontend:v1 frontend/
docker push $ACCOUNT.dkr.ecr.$REGION.amazonaws.com/dating-app-frontend:v1

Step 2: Create RDS PostgreSQL

# Via AWS Console or CLI
aws rds create-db-instance \
  --db-instance-identifier dating-app-db \
  --db-instance-class db.t3.micro \
  --engine postgres \
  --master-username dating_user \
  --master-user-password <secure-password> \
  --allocated-storage 20

Step 3: Prepare Helm Values for AWS

cp helm/dating-app/values-aws.yaml aws-values.yaml

Edit aws-values.yaml:

backend:
  image:
    repository: <account>.dkr.ecr.us-east-1.amazonaws.com/dating-app-backend
    tag: v1
  environment:
    DATABASE_URL: postgresql://dating_user:<password>@<rds-endpoint>.rds.amazonaws.com:5432/dating_app
    JWT_SECRET: <generate-secure-secret>
    CORS_ORIGINS: "https://yourdomain.com,https://api.yourdomain.com"

frontend:
  image:
    repository: <account>.dkr.ecr.us-east-1.amazonaws.com/dating-app-frontend
    tag: v1
  environment:
    VITE_API_URL: "https://api.yourdomain.com"

backend:
  ingress:
    host: api.yourdomain.com

frontend:
  ingress:
    host: yourdomain.com

ingress:
  annotations:
    alb.ingress.kubernetes.io/certificate-arn: "arn:aws:acm:us-east-1:<account>:certificate/<id>"

Step 4: Deploy to EKS

# Update kubeconfig
aws eks update-kubeconfig --name <cluster-name> --region us-east-1

# Deploy
helm install dating-app ./helm/dating-app \
  -n dating-app \
  --create-namespace \
  -f aws-values.yaml

# Verify
kubectl get all -n dating-app

Step 5: Configure Route 53

# Create Route 53 records pointing to ALB DNS name
# Get ALB DNS:
kubectl get ingress -n dating-app -o wide

Upgrading Deployment

Update Images

# Build new images
docker build -t $REGISTRY/dating-app-backend:v2 backend/
docker push $REGISTRY/dating-app-backend:v2

# Update values
# In my-values.yaml, change tag: v1 to tag: v2

# Upgrade Helm release
helm upgrade dating-app ./helm/dating-app \
  -n dating-app \
  -f my-values.yaml

Database Migrations

The backend automatically initializes/migrates the schema on startup.

For manual migrations (if using Alembic in future):

kubectl exec -it -n dating-app <backend-pod> -- \
  alembic upgrade head

Rollback

# View release history
helm history dating-app -n dating-app

# Rollback to previous version
helm rollback dating-app <revision> -n dating-app

Scaling

Horizontal Pod Autoscaler (Future Enhancement)

kubectl autoscale deployment backend -n dating-app \
  --min=2 --max=10 --cpu-percent=80

Manual Scaling

# Scale backend
kubectl scale deployment backend -n dating-app --replicas=3

# Scale frontend
kubectl scale deployment frontend -n dating-app --replicas=3

Backup and Recovery

PostgreSQL Backup (RDS)

# AWS handles automated backups. For manual backup:
aws rds create-db-snapshot \
  --db-instance-identifier dating-app-db \
  --db-snapshot-identifier dating-app-snapshot-$(date +%Y%m%d)

Backup PersistentVolumes

# Create snapshot of media PVC
kubectl patch pvc backend-media-pvc -n dating-app \
  --type merge -p '{"metadata":{"finalizers":["protect"]}}'

Monitoring

Logs

# View logs
kubectl logs -n dating-app deployment/backend -f
kubectl logs -n dating-app deployment/frontend -f

# View previous logs if pod crashed
kubectl logs -n dating-app deployment/backend --previous

Resource Usage

kubectl top pods -n dating-app
kubectl top nodes

Health Checks

# Check endpoint health
curl http://api.yourdomain.com/health

Troubleshooting

Pod Won't Start

# Check events
kubectl describe pod -n dating-app <pod-name>

# Check logs
kubectl logs -n dating-app <pod-name> --previous

Database Connection Issues

# Test database connectivity
kubectl run -it --rm debug --image=postgres:15-alpine \
  --restart=Never -n dating-app -- \
  psql -h postgres -U dating_user -d dating_app -c "SELECT 1"

Image Pull Errors

# Verify image exists in registry
docker pull <your-registry>/dating-app-backend:v1

# Check image pull secret if needed
kubectl create secret docker-registry regcred \
  --docker-server=<registry> \
  --docker-username=<user> \
  --docker-password=<pass> \
  -n dating-app

Performance Tuning

Database Optimization

-- Create indexes for common queries
CREATE INDEX idx_profiles_created_at ON profiles(created_at DESC);
CREATE INDEX idx_conversations_users ON conversations(user_id_1, user_id_2);

Resource Limits

Adjust in values.yaml based on your infrastructure:

resources:
  requests:
    memory: "512Mi"
    cpu: "200m"
  limits:
    memory: "1Gi"
    cpu: "500m"

Security Hardening

Network Policies

# Restrict traffic between pods
kubectl apply -f - <<EOF
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: dating-app-netpol
  namespace: dating-app
spec:
  podSelector:
    matchLabels:
      app: backend
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: frontend
    ports:
    - protocol: TCP
      port: 8000
EOF

TLS/SSL

Enable in Ingress with cert-manager:

ingress:
  annotations:
    cert-manager.io/cluster-issuer: "letsencrypt-prod"

Uninstalling

# Remove Helm release
helm uninstall dating-app -n dating-app

# Remove namespace
kubectl delete namespace dating-app