Dating App MVP - Full Stack Kubernetes Deployment
A complete MVP dating application with user profiles, photo uploads, and 1:1 chat. Built with modern technologies and designed to run on home-lab Kubernetes with easy portability to AWS.
📋 Features
Authentication
- User registration with email verification
- Login with JWT access tokens
- Password hashing with bcrypt
- Protected endpoints with Authorization header
User Profiles
- Create and update profiles with:
- Display name
- Age
- Gender
- Location
- Bio
- Interests (tags)
- Discover endpoint for profile recommendations
- Simple filtering (exclude self)
Photo Management
- Upload multiple profile photos
- Store on local disk (with S3 migration path)
- Photos served via
/media/endpoint - Database metadata tracking
Likes & Matches
- Like/heart other users
- Automatic match detection (mutual likes)
- Matches list endpoint
1:1 Chat
- Send and receive messages between matched users
- Message history for each conversation
- Real-time polling (WebSocket ready for future enhancement)
- Conversation list with latest message preview
🏗️ Architecture
aws-final-project/
├── backend/ # FastAPI Python backend
│ ├── app/
│ │ ├── models/ # Database models
│ │ ├── schemas/ # Pydantic schemas
│ │ ├── routers/ # API route handlers
│ │ ├── services/ # Business logic
│ │ ├── auth/ # JWT & auth utilities
│ │ ├── db.py # Database connection & init
│ │ └── config.py # Configuration
│ ├── main.py # FastAPI application
│ ├── requirements.txt # Python dependencies
│ ├── Dockerfile # Backend container
│ ├── .env.example # Environment template
│ └── alembic/ # Database migrations (setup for future use)
├── frontend/ # React + Vite frontend
│ ├── src/
│ │ ├── pages/ # Page components
│ │ ├── styles/ # CSS modules
│ │ ├── api.js # Centralized API client
│ │ ├── App.jsx # Main app component
│ │ └── main.jsx # React entry point
│ ├── package.json # Node dependencies
│ ├── vite.config.js # Vite configuration
│ ├── Dockerfile # Frontend nginx container
│ ├── nginx.conf # Nginx configuration
│ ├── .env.example # Environment template
│ └── index.html # HTML template
├── docker-compose.yml # Local development compose
├── helm/ # Kubernetes Helm chart
│ └── dating-app/
│ ├── Chart.yaml # Chart metadata
│ ├── values.yaml # Default values
│ ├── values-lab.yaml # Lab/home-lab values
│ ├── values-aws.yaml # AWS deployment values
│ ├── templates/ # K8s resource templates
│ └── README.md # Helm chart docs
└── README.md # This file
🚀 Quick Start
Local Development (Docker Compose)
Prerequisites:
- Docker
- Docker Compose
# Clone and navigate
cd aws-final-project
# Copy environment files
cp backend/.env.example backend/.env
cp frontend/.env.example frontend/.env
# Build and start
docker-compose up -d
# Application ready at:
# Frontend: http://localhost:3000
# Backend: http://localhost:8000
# API Docs: http://localhost:8000/docs
Home-Lab Kubernetes Deployment
Prerequisites:
- Kubernetes cluster (1.19+)
- Helm 3+
- Nginx Ingress Controller
- Storage provisioner
# Build and push images to your registry
docker build -t my-registry/dating-app-backend:v1 backend/
docker build -t my-registry/dating-app-frontend:v1 frontend/
docker push my-registry/dating-app-backend:v1
docker push my-registry/dating-app-frontend:v1
# Create values file for your lab
cp helm/dating-app/values-lab.yaml my-values.yaml
# Edit my-values.yaml with your registry URLs and domain
# Deploy with Helm
helm install dating-app ./helm/dating-app \
-n dating-app \
--create-namespace \
-f my-values.yaml
# Verify deployment
kubectl get pods -n dating-app
kubectl get svc -n dating-app
kubectl get ingress -n dating-app
AWS Deployment
Prerequisites:
- AWS account with EKS cluster
- RDS PostgreSQL instance
- S3 bucket for images (optional)
- Container registry (ECR)
# Build and push 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
docker tag dating-app-backend:v1 <account>.dkr.ecr.us-east-1.amazonaws.com/dating-app-backend:v1
docker push <account>.dkr.ecr.us-east-1.amazonaws.com/dating-app-backend:v1
# Prepare values for AWS
cp helm/dating-app/values-aws.yaml my-aws-values.yaml
# Edit with your RDS endpoint, ACM certificate, domain, etc.
# Deploy
helm install dating-app ./helm/dating-app \
-n dating-app \
--create-namespace \
-f my-aws-values.yaml
📡 API Endpoints
Authentication
POST /auth/register- Register new userPOST /auth/login- Login userGET /auth/me- Current user info (protected)
Profiles
POST /profiles/- Create/update profile (protected)GET /profiles/me- Get own profile (protected)GET /profiles/{user_id}- Get user profile (protected)GET /profiles/discover/list- Get profiles to discover (protected)
Photos
POST /photos/upload- Upload photo (protected)GET /photos/{photo_id}- Get photo info (protected)DELETE /photos/{photo_id}- Delete photo (protected)
Likes
POST /likes/{user_id}- Like a user (protected)GET /likes/matches/list- Get matches (protected)
Chat
GET /chat/conversations- List conversations (protected)GET /chat/conversations/{conv_id}/messages- Get messages (protected)POST /chat/conversations/{conv_id}/messages- Send message (protected)
🔧 Configuration
Backend Environment Variables
DATABASE_URL=postgresql://user:password@host:5432/database
JWT_SECRET=your-secret-key
JWT_EXPIRES_MINUTES=1440
MEDIA_DIR=/app/media
CORS_ORIGINS=http://localhost:3000,http://localhost:5173
Frontend Environment Variables
VITE_API_URL=http://localhost:8000
📦 Technology Stack
Backend
- Framework: FastAPI 0.104+
- Server: Uvicorn
- Database: PostgreSQL 15
- Driver: psycopg2 (synchronous)
- Auth: JWT + bcrypt
- Validation: Pydantic
Frontend
- Framework: React 18
- Build Tool: Vite
- HTTP Client: Axios
- Styling: CSS Modules
- State: localStorage for JWT
Infrastructure
- Containers: Docker
- Orchestration: Kubernetes
- Package Manager: Helm
- Ingress: Nginx/Traefik compatible
🔐 Security Notes
Current Implementation
- Passwords hashed with bcrypt
- JWT tokens with expiration
- CORS configured
- Protected endpoints
For Production
- Use strong JWT_SECRET (generate:
openssl rand -hex 32) - Enable HTTPS/TLS in Ingress
- Use external secrets management (Vault, AWS Secrets Manager)
- Implement rate limiting
- Add request validation and sanitization
- Enable database SSL connections
- Regular security updates for dependencies
🌐 AWS Migration Guide
Switch from Local Storage to S3
- Update backend environment:
STORAGE_TYPE=s3
AWS_BUCKET_NAME=your-bucket
AWS_REGION=us-east-1
- Modify backend/app/services/photo_service.py to use boto3
- Update media serving to redirect to S3 presigned URLs
Switch from Local PostgreSQL to RDS
- Create RDS instance in AWS
- Update values in Helm chart:
postgres:
enabled: false # Disable embedded Postgres
backend:
environment:
DATABASE_URL: postgresql://user:pass@rds-endpoint.amazonaws.com:5432/db
- Deploy with updated values
Load Balancer & Auto-scaling
Helm chart supports AWS Application Load Balancer (ALB):
ingress:
className: aws-alb
annotations:
alb.ingress.kubernetes.io/scheme: internet-facing
Set replicas in values for auto-scaling base:
backend:
replicas: 3
frontend:
replicas: 3
🧪 Testing
API Testing with curl
# Register
curl -X POST http://localhost:8000/auth/register \
-H "Content-Type: application/json" \
-d '{
"email": "user@example.com",
"password": "password123",
"display_name": "John Doe"
}'
# Login
curl -X POST http://localhost:8000/auth/login \
-H "Content-Type: application/json" \
-d '{
"email": "user@example.com",
"password": "password123"
}'
# Update profile (use token from login response)
curl -X POST http://localhost:8000/profiles/ \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"display_name": "John Doe",
"age": 28,
"gender": "male",
"location": "San Francisco",
"bio": "Looking for someone...",
"interests": ["hiking", "travel"]
}'
Swagger UI
Visit http://localhost:8000/docs for interactive API documentation.
📝 Database Schema
Tables
users- User accounts with email and hashed passwordsprofiles- User profile informationphotos- User photos with file pathslikes- Like relationships between usersconversations- 1:1 chat conversationsmessages- Chat messages
All tables include proper timestamps and foreign key constraints.
🔄 Development Workflow
Adding a New Feature
-
Backend
- Add database model/schema if needed
- Implement service logic
- Create router endpoints
- Document in API
-
Frontend
- Add API calls to frontend/src/api.js
- Create React components
- Add styling
-
Test
- Test locally with docker-compose
- Test in Kubernetes with Helm
Building Images for Testing
# Backend
docker build -t dating-app-backend:test -f backend/Dockerfile backend/
# Frontend
docker build -t dating-app-frontend:test -f frontend/Dockerfile frontend/
# Test with compose
docker-compose -f docker-compose.yml up
🐛 Troubleshooting
Backend Issues
# Check logs
docker logs dating_app_backend
# Check database connection
docker exec dating_app_backend curl http://localhost:8000/health
Frontend Issues
# Check logs
docker logs dating_app_frontend
# Check API connectivity
curl http://localhost:8000/health
Kubernetes Issues
# Check pod status
kubectl describe pod -n dating-app <pod-name>
# View logs
kubectl logs -n dating-app <pod-name>
# Port forward for debugging
kubectl port-forward -n dating-app svc/backend 8000:8000
kubectl port-forward -n dating-app svc/frontend 3000:80
📚 Additional Resources
- FastAPI Documentation
- React Documentation
- Kubernetes Documentation
- Helm Documentation
- PostgreSQL Documentation
📄 License
This is an educational MVP project. Use freely for learning purposes.
🤝 Contributing
Contributions welcome! Areas for improvement:
- WebSocket implementation for real-time chat
- File upload progress tracking
- Image optimization and compression
- Database query optimization
- Frontend component refinement
- Comprehensive test suite
- CI/CD pipeline setup
📞 Support
For issues or questions:
- Check existing documentation
- Review API documentation at
/docs - Check application logs
- Verify environment variables and configuration