# Deployment Guide

This guide covers deploying the dating app to different environments.

## Local Development (Docker Compose)

### Quick Start

```bash
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

- **Frontend:** http://localhost:3000
- **Backend API:** http://localhost:8000
- **API Documentation:** http://localhost:8000/docs
- **PostgreSQL:** localhost:5432

### Development Mode

For development with hot reload:

```bash
# 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

```bash
docker-compose down -v  # Remove volumes too
```

## Kubernetes Deployment (Home-Lab)

### Prerequisites

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

### Step 1: Build and Push Images

```bash
# 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

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

Edit `my-values.yaml`:
```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

```bash
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:
```bash
# 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:
```bash
kubectl port-forward -n dating-app svc/frontend 3000:80
kubectl port-forward -n dating-app svc/backend 8000:8000
```

### Monitoring Deployment

```bash
# 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

```bash
# 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

```bash
# 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

```bash
# 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

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

Edit `aws-values.yaml`:

```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

```bash
# 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

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

## Upgrading Deployment

### Update Images

```bash
# 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):
```bash
kubectl exec -it -n dating-app <backend-pod> -- \
  alembic upgrade head
```

## Rollback

```bash
# 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)

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

### Manual Scaling

```bash
# 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)

```bash
# 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

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

## Monitoring

### Logs

```bash
# 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

```bash
kubectl top pods -n dating-app
kubectl top nodes
```

### Health Checks

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

## Troubleshooting

### Pod Won't Start

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

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

### Database Connection Issues

```bash
# 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

```bash
# 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

```sql
-- 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:
```yaml
resources:
  requests:
    memory: "512Mi"
    cpu: "200m"
  limits:
    memory: "1Gi"
    cpu: "500m"
```

## Security Hardening

### Network Policies

```yaml
# 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:
```yaml
ingress:
  annotations:
    cert-manager.io/cluster-issuer: "letsencrypt-prod"
```

## Uninstalling

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

# Remove namespace
kubectl delete namespace dating-app
```
