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

460 lines
8.8 KiB
Markdown

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