| version: '3.8' | |
| services: | |
| # ==================== BACKEND API - Scalable Workers ==================== | |
| backend: | |
| build: | |
| context: . | |
| dockerfile: Dockerfile | |
| restart: unless-stopped | |
| env_file: | |
| - .env | |
| # environment: | |
| # # Core Settings | |
| # - NODE_ENV=${NODE_ENV:-production} | |
| # - PORT=${PORT:-3000} | |
| # - API_PREFIX=${API_PREFIX:-/api} | |
| # # Database (Cloud MongoDB Atlas) | |
| # - MONGODB_URL=${MONGODB_URL} | |
| # # Redis (Cloud Redis Labs) | |
| # - REDIS_URL=${REDIS_URL} | |
| # # JWT | |
| # - JWT_SECRET=${JWT_SECRET} | |
| # - EMAIL_SERVICE=gmail | |
| # - EMAIL_USER=${EMAIL_USER} | |
| # - EMAIL_PASS=${EMAIL_APP_PASSWORD} | |
| # # Frontend & CORS | |
| # - ALLOWED_ORIGINS=${ALLOWED_ORIGINS} | |
| # - FRONTEND_URL=${FRONTEND_URL} | |
| # # Cloudinary | |
| # - CLOUDINARY_API_KEY=${CLOUDINARY_API_KEY} | |
| # - CLOUDINARY_API_SECRET=${CLOUDINARY_API_SECRET} | |
| # - CLOUDINARY_CLOUD_NAME=${CLOUDINARY_CLOUD_NAME} | |
| # # Google OAuth | |
| # - GOOGLE_CLIENT_ID=${GOOGLE_CLIENT_ID} | |
| # - GOOGLE_CLIENT_SECRET=${GOOGLE_CLIENT_SECRET} | |
| # # Razorpay | |
| # - RZP_KEY_ID=${RZP_KEY_ID} | |
| # - RZP_KEY_SECRET=${RZP_KEY_SECRET} | |
| # # AI API | |
| # - VERMARJUN_API_KEY=${VERMARJUN_API_KEY} | |
| # - VERMARJUN_BASE_URL=${VERMARJUN_BASE_URL} | |
| # - VERMARJUN_MODEL_NAME=${VERMARJUN_MODEL_NAME} | |
| # # Microservice | |
| # - MICROSERVICE_URL=${MICROSERVICE_URL} | |
| healthcheck: | |
| test: ["CMD", "node", "-e", "require('http').get('http://localhost:3000${API_PREFIX}/health', (r) => { process.exit(r.statusCode === 200 ? 0 : 1) })"] | |
| interval: 30s | |
| timeout: 10s | |
| retries: 3 | |
| start_period: 40s | |
| networks: | |
| - backend-network | |
| # Resource limits (adjust based on your needs) | |
| deploy: | |
| resources: | |
| limits: | |
| cpus: '0.5' | |
| memory: 512M | |
| reservations: | |
| cpus: '0.25' | |
| memory: 256M | |
| # ==================== NGINX - Load Balancer ==================== | |
| nginx: | |
| image: nginx:alpine | |
| container_name: nginx | |
| restart: unless-stopped | |
| ports: | |
| - "80:80" | |
| - "443:443" | |
| volumes: | |
| - ./nginx.conf:/etc/nginx/nginx.conf:ro | |
| - ./nginx-logs:/var/log/nginx | |
| depends_on: | |
| - backend | |
| healthcheck: | |
| test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost/api/health"] | |
| interval: 30s | |
| timeout: 10s | |
| retries: 3 | |
| networks: | |
| - backend-network | |
| # ==================== NETWORKS ==================== | |
| networks: | |
| backend-network: | |
| driver: bridge | |
| # ============================================================================ | |
| # USAGE COMMANDS: | |
| # ============================================================================ | |
| # Start with 4 backend workers: | |
| # docker-compose up -d --build --scale backend=4 | |
| # | |
| # Scale to 8 workers: | |
| # docker-compose up -d --scale backend=8 | |
| # | |
| # Scale down to 2 workers: | |
| # docker-compose up -d --scale backend=2 | |
| # | |
| # View logs: | |
| # docker-compose logs -f backend | |
| # | |
| # View all services: | |
| # docker-compose ps | |
| # | |
| # Stop all services: | |
| # docker-compose down | |
| # | |
| # Rebuild backend after code changes: | |
| # docker-compose build backend | |
| # docker-compose up -d --scale backend=4 | |
| # | |
| # Test health endpoint: | |
| # curl http://localhost/api/health | |
| # | |
| # Test load balancing: | |
| # for i in {1..20}; do curl -s http://localhost/api/health | jq -r '.instance'; done | |
| # ============================================================================ |