460 lines
8.8 KiB
Markdown
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
|
|
```
|