version: '3.8' services: # PostgreSQL Database postgres: image: postgres:15-alpine container_name: drone-detection-db restart: unless-stopped environment: POSTGRES_DB: drone_detection POSTGRES_USER: postgres POSTGRES_PASSWORD: postgres123 PGDATA: /var/lib/postgresql/data/pgdata volumes: - postgres_data:/var/lib/postgresql/data - ./server/scripts/init-db.sql:/docker-entrypoint-initdb.d/init-db.sql ports: - "5433:5432" networks: - drone-network healthcheck: test: ["CMD-SHELL", "pg_isready -U postgres -d drone_detection"] interval: 30s timeout: 10s retries: 3 # Redis for session management and caching redis: image: redis:7-alpine container_name: drone-detection-redis restart: unless-stopped command: redis-server --appendonly yes volumes: - redis_data:/data ports: - "6380:6379" networks: - drone-network healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 30s timeout: 10s retries: 3 # Backend API Server backend: build: context: ./server dockerfile: Dockerfile container_name: drone-detection-backend restart: unless-stopped environment: NODE_ENV: production PORT: 3001 DB_HOST: postgres DB_PORT: 5432 DB_NAME: drone_detection DB_USER: postgres DB_PASSWORD: postgres123 REDIS_HOST: redis REDIS_PORT: 6379 JWT_SECRET: ${JWT_SECRET:-your-super-secret-jwt-key-change-in-production} TWILIO_ACCOUNT_SID: ${TWILIO_ACCOUNT_SID} TWILIO_AUTH_TOKEN: ${TWILIO_AUTH_TOKEN} TWILIO_PHONE_NUMBER: ${TWILIO_PHONE_NUMBER} CORS_ORIGIN: http://localhost:3001 API_DEBUG: ${API_DEBUG:-false} ports: - "3002:3001" volumes: - ./server/logs:/app/logs networks: - drone-network depends_on: postgres: condition: service_healthy redis: condition: service_healthy healthcheck: test: ["CMD", "curl", "-f", "http://localhost:3001/api/health"] interval: 30s timeout: 10s retries: 3 # Frontend React Application frontend: build: context: ./client dockerfile: Dockerfile args: VITE_API_URL: ${VITE_API_URL:-/drones/api} VITE_WS_URL: ${VITE_WS_URL:-/drones} NODE_ENV: production container_name: drone-detection-frontend restart: unless-stopped ports: - "3001:80" networks: - drone-network depends_on: - backend healthcheck: test: ["CMD", "curl", "-f", "http://localhost:80"] interval: 30s timeout: 10s retries: 3 # Nginx Reverse Proxy (Production) nginx: image: nginx:alpine container_name: drone-detection-nginx restart: unless-stopped ports: - "8080:80" - "8443:443" volumes: - ./docker/nginx/nginx.conf:/etc/nginx/nginx.conf - ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf - ./docker/ssl:/etc/nginx/ssl - ./client/dist:/usr/share/nginx/html networks: - drone-network depends_on: - frontend - backend profiles: - production # Python Drone Simulator (Optional) simulator: build: context: . dockerfile: docker/simulator/Dockerfile container_name: drone-detection-simulator restart: "no" environment: API_URL: http://backend:3001/api networks: - drone-network depends_on: - backend profiles: - simulation command: python drone_simulator.py --devices 5 --duration 3600 # Health Probe Simulator (Continuous Device Heartbeats) healthprobe: build: context: . dockerfile: Dockerfile.healthprobe container_name: drone-detection-healthprobe restart: unless-stopped environment: PROBE_FAILRATE: ${PROBE_FAILRATE:-30} PROBE_INTERVAL_SECONDS: ${PROBE_INTERVAL_SECONDS:-60} API_BASE_URL: http://backend:3001/api networks: - drone-network depends_on: backend: condition: service_healthy profiles: - healthprobe volumes: postgres_data: driver: local redis_data: driver: local networks: drone-network: driver: bridge