A production-ready, microservices-based fitness tracking application with enterprise-grade architecture featuring load balancing, distributed rate limiting, and horizontal scaling capabilities.
- ✅ Microservices Architecture - Modular, scalable service design
- ✅ Load Balancing - NGINX-powered distribution across multiple API gateways
- ✅ Distributed Rate Limiting - Redis-based rate limiting across all instances
- ✅ JWT Authentication - Secure user authentication with refresh tokens
- ✅ Email Verification - Complete user verification workflow
- ✅ Password Reset - Secure password recovery system
- ✅ Workout Tracking - Comprehensive fitness data management
- ✅ Real-time Notifications - User notification system
- ✅ Health Monitoring - Built-in health checks for all services
- ✅ Container Orchestration - Docker Compose for easy deployment
- ✅ Type Safety - Full TypeScript implementation
- ✅ Database Migrations - Prisma-powered schema management
graph TB
Client[Client Applications]
subgraph "Load Balancer Layer"
LB[NGINX Load Balancer<br/>Port: 8080]
end
subgraph "API Gateway Layer"
GW1[API Gateway 1<br/>Port: 3001]
GW2[API Gateway 2<br/>Port: 3002]
GW3[API Gateway 3<br/>Port: 3003]
end
subgraph "Microservices Layer"
US[User Service<br/>Port: 3005]
WS[Workout Service<br/>Port: 3006]
end
subgraph "Data Layer"
Redis[(Redis<br/>Rate Limiting & Cache)]
DB[(PostgreSQL<br/>Primary Database)]
end
Client --> LB
LB --> GW1
LB --> GW2
LB --> GW3
GW1 --> US
GW1 --> WS
GW2 --> US
GW2 --> WS
GW3 --> US
GW3 --> WS
GW1 --> Redis
GW2 --> Redis
GW3 --> Redis
US --> DB
WS --> DB
- Docker & Docker Compose (v20.10+)
- Node.js (v18+) - For local development
- Git - For cloning the repository
git clone https://github.com/your-username/fitness-tracker2.git
cd fitness-tracker2
# Copy environment template
cp .env.example .env
# Configure your environment variables
# Edit .env with your specific configuration
# Database Configuration
DATABASE_URL="postgresql://username:password@localhost:5432/fitness_tracker"
# JWT Secrets (Generate secure keys)
JWT_SECRET=your_super_secure_jwt_secret_key_here_minimum_32_chars
JWT_REFRESH_SECRET=your_super_secure_refresh_secret_key_here_minimum_32_chars
# Email Configuration
EMAIL_USER=[email protected]
EMAIL_PASS=your-app-specific-password
# Redis Configuration
REDIS_URL=redis://redis:6379
# Environment
NODE_ENV=production
.\deploy.ps1
chmod +x deploy.sh
./deploy.sh
Once deployed, verify all services are running:
# Check overall health
curl http://localhost:8080/health
# Check individual gateways
curl http://localhost:3001/health
curl http://localhost:3002/health
curl http://localhost:3003/health
# Check services
curl http://localhost:3005/health
curl http://localhost:3006/health
Method | Endpoint | Description |
---|---|---|
POST |
/api/auth/signup |
User registration |
POST |
/api/auth/login |
User login |
POST |
/api/auth/refresh |
Refresh access token |
POST |
/api/auth/logout |
User logout |
POST |
/api/auth/forgot-password |
Request password reset |
POST |
/api/auth/reset-password |
Reset password |
POST |
/api/auth/verify-email |
Verify email address |
Method | Endpoint | Description |
---|---|---|
GET |
/api/user/profile |
Get user profile |
PUT |
/api/user/profile |
Update user profile |
GET |
/api/user/notifications |
Get user notifications |
PUT |
/api/user/notifications/:id |
Update notification |
Method | Endpoint | Description |
---|---|---|
GET |
/api/workout |
Get user workouts |
POST |
/api/workout |
Create new workout |
GET |
/api/workout/:id |
Get specific workout |
PUT |
/api/workout/:id |
Update workout |
DELETE |
/api/workout/:id |
Delete workout |
Method | Endpoint | Description |
---|---|---|
GET |
/health |
Service health status |
GET |
/nginx-health |
NGINX load balancer health |
- Global Rate Limiting: 100 requests per 15 minutes per IP
- Authentication Endpoints: 20 requests per 15 minutes per IP
- Distributed: Shared across all API gateway instances via Redis
- Helmet.js: Security headers implementation
- CORS: Cross-origin resource sharing protection
- JWT: Secure token-based authentication
- Password Hashing: bcrypt with salt rounds
- Joi Validation: Schema-based request validation
- Type Safety: TypeScript for compile-time type checking
- Sanitization: Input sanitization for SQL injection prevention
All services expose health check endpoints:
# Check API Gateway health
curl http://localhost:3001/health
# Expected response:
{
"status": "OK",
"gateway": "gateway-1",
"timestamp": "2025-06-26T12:00:00.000Z"
}
- Gateway Level: Request routing and load balancing logs
- Service Level: Individual service request logs
- NGINX Level: Access and error logs
logs/
├── nginx/
│ ├── access.log # NGINX access logs
│ └── error.log # NGINX error logs
└── [service-logs appear in Docker logs]
Table users {
id String [pk]
email String [unique]
password String
username String
isVerified Boolean [default: false]
verificationToken String
verificationTokenExpiry DateTime
refreshToken String
passwordResetToken String
passwordResetTokenExpiry DateTime
createdAt DateTime [default: now()]
updatedAt DateTime [updatedAt]
}
Table workouts {
id String [pk]
userId String [ref: > users.id]
date DateTime
exerciseType ExerciseType
duration Int // minutes
calories Int
}
Table notifications {
id String [pk]
userId String [ref: > users.id]
message String
isRead Boolean [default: false]
createdAt DateTime [default: now()]
}
-
Install dependencies:
npm install npx lerna bootstrap
-
Setup database:
cd packages/shared npx prisma migrate dev npx prisma generate
-
Start services individually:
# Terminal 1: User Service cd packages/user-service npm run dev # Terminal 2: Workout Service cd packages/workout-service npm run dev # Terminal 3: API Gateway cd packages/api-gateway npm run dev
# Install dependencies for all packages
npm run bootstrap
# Build all packages
npm run build
# Run tests
npm run test
# Lint code
npm run lint
# Deploy with Docker
npm run deploy
fitness-tracker2/
├── packages/
│ ├── api-gateway/ # API Gateway service
│ │ ├── src/
│ │ ├── Dockerfile
│ │ └── package.json
│ ├── user-service/ # User management service
│ │ ├── src/
│ │ │ ├── auth/ # Authentication logic
│ │ │ ├── user-profile/ # Profile management
│ │ │ └── utils/ # Utility functions
│ │ ├── Dockerfile
│ │ └── package.json
│ ├── workout-service/ # Workout management service
│ │ ├── src/
│ │ │ ├── controllers/ # Request controllers
│ │ │ ├── routes/ # API routes
│ │ │ └── validation/ # Input validation
│ │ ├── Dockerfile
│ │ └── package.json
│ └── shared/ # Shared utilities and database
│ ├── prisma/ # Database schema and migrations
│ ├── generated/ # Generated Prisma client
│ └── package.json
├── logs/ # Log files
├── docker-compose.yml # Container orchestration
├── nginx.conf # Load balancer configuration
├── deploy.ps1 # Windows deployment script
├── deploy.sh # Unix deployment script
└── README.md # This file
The load balancer distributes requests across three API Gateway instances using round-robin algorithm:
upstream api_gateways {
server api-gateway-1:3000;
server api-gateway-2:3000;
server api-gateway-3:3000;
keepalive 32;
}
# Make multiple requests to see different gateways respond
for i in {1..6}; do
curl -s http://localhost:8080/health | grep gateway
done
# Expected output shows rotation between gateway-1, gateway-2, gateway-3
Service | Container Name | Port | Purpose |
---|---|---|---|
nginx-lb | fitness-nginx-lb | 8080 | Load balancer |
redis | fitness-redis | 6379 | Rate limiting & cache |
user-service | fitness-user-service | 3005 | User management |
workout-service | fitness-workout-service | 3006 | Workout management |
api-gateway-1 | fitness-api-gateway-1 | 3001 | API Gateway instance 1 |
api-gateway-2 | fitness-api-gateway-2 | 3002 | API Gateway instance 2 |
api-gateway-3 | fitness-api-gateway-3 | 3003 | API Gateway instance 3 |
To add more API Gateway instances:
-
Add new service in
docker-compose.yml
:api-gateway-4: build: context: . dockerfile: packages/api-gateway/Dockerfile container_name: fitness-api-gateway-4 environment: - GATEWAY_ID=gateway-4 ports: - "3004:3000"
-
Update NGINX upstream configuration:
upstream api_gateways { server api-gateway-1:3000; server api-gateway-2:3000; server api-gateway-3:3000; server api-gateway-4:3000; # New instance }
Adjust Docker resource limits in docker-compose.yml
:
services:
api-gateway-1:
deploy:
resources:
limits:
cpus: '0.50'
memory: 512M
reservations:
cpus: '0.25'
memory: 256M
# Test user registration
curl -X POST http://localhost:8080/api/auth/signup \
-H "Content-Type: application/json" \
-d '{"email":"[email protected]","password":"securepassword123","username":"testuser"}'
# Test user login
curl -X POST http://localhost:8080/api/auth/login \
-H "Content-Type: application/json" \
-d '{"email":"[email protected]","password":"securepassword123"}'
# Test workout creation (requires authentication token)
curl -X POST http://localhost:8080/api/workout \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-d '{"exerciseType":"CARDIO","duration":30,"calories":200,"date":"2025-06-26T10:00:00Z"}'
# Install Apache Bench for load testing
sudo apt-get install apache2-utils
# Test with 100 concurrent requests
ab -n 1000 -c 100 http://localhost:8080/health
-
Services not starting:
# Check Docker logs docker-compose logs [service-name] # Restart specific service docker-compose restart [service-name]
-
Database connection issues:
# Check database connectivity docker-compose exec user-service npx prisma migrate status
-
Redis connection issues:
# Test Redis connectivity docker-compose exec redis redis-cli ping
-
Port conflicts:
# Check port usage netstat -tulpn | grep :8080 # Stop conflicting services sudo systemctl stop nginx # If system nginx is running
# View all running containers
docker-compose ps
# Follow logs for all services
docker-compose logs -f
# Execute commands in containers
docker-compose exec user-service sh
docker-compose exec redis redis-cli
# Check service health
docker-compose exec api-gateway-1 curl localhost:3000/health
# Redis memory usage
docker-compose exec redis redis-cli info memory
# Redis performance monitoring
docker-compose exec redis redis-cli monitor
-- Add indexes for better query performance
CREATE INDEX idx_workouts_user_id ON workouts(userId);
CREATE INDEX idx_workouts_date ON workouts(date);
CREATE INDEX idx_notifications_user_id ON notifications(userId);
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature
- Commit your changes:
git commit -m 'Add amazing feature'
- Push to the branch:
git push origin feature/amazing-feature
- Open a Pull Request
- TypeScript: Use strict type checking
- ESLint: Follow the established linting rules
- Testing: Write tests for new features
- Documentation: Update README for new features
- Security: Follow security best practices
This project is licensed under the MIT License - see the LICENSE file for details.
- Express.js - Fast, unopinionated web framework
- Prisma - Modern database toolkit
- Redis - In-memory data structure store
- Docker - Containerization platform
- NGINX - High-performance web server and load balancer
- TypeScript - Typed superset of JavaScript
For support and questions:
- Create an Issue: GitHub Issues
- Documentation: Check this README and inline code comments
- Email: [email protected]
Built with ❤️ by the Fitness Tracker Team