version: '3.8' services: # Database Service db: image: postgres:15-alpine container_name: controlpatente-db environment: POSTGRES_USER: ${DB_USER:-postgres} POSTGRES_PASSWORD: ${DB_PASSWORD:-postgres} POSTGRES_DB: ${DB_NAME:-controlpatente} volumes: - db_data:/var/lib/postgresql/data # SECURITY: Port not exposed externally - only accessible within Docker network # Uncomment for local development debugging only # ports: # - "5432:5432" networks: - backend-net restart: unless-stopped healthcheck: test: [ "CMD-SHELL", "pg_isready -U postgres" ] interval: 5s timeout: 5s retries: 5 logging: driver: "json-file" options: max-size: "10m" max-file: "3" # Backend Service (Node.js) backend: build: ./backend container_name: controlpatente-backend environment: - DATABASE_URL=postgresql://${DB_USER:-postgres}:${DB_PASSWORD:-postgres}@db:5432/${DB_NAME:-controlpatente} - PORT=3000 - JWT_SECRET=${JWT_SECRET:?JWT_SECRET is required} - ADMIN_PASSWORD=${ADMIN_PASSWORD:-} - ALLOWED_ORIGINS=${ALLOWED_ORIGINS:-http://localhost:5173} - SERVICE_API_KEY=${SERVICE_API_KEY:-} ports: - "3000:3000" depends_on: db: condition: service_healthy networks: - backend-net restart: unless-stopped volumes: - ./backend:/app - /app/node_modules healthcheck: test: [ "CMD", "wget", "-q", "--spider", "http://localhost:3000/api/health" ] interval: 30s timeout: 10s retries: 3 start_period: 40s logging: driver: "json-file" options: max-size: "10m" max-file: "3" # ALPR Component (Python + OpenCV) alpr-service: build: ./alpr-service container_name: controlpatente-alpr ports: - "5001:5001" environment: - BACKEND_URL=http://backend:3000 - PROCESS_INTERVAL=1.5 - DATASET_COOLDOWN=60 - OCR_WORKERS=2 - SERVICE_API_KEY=${SERVICE_API_KEY:-} devices: - "/dev/video0:/dev/video0" networks: - backend-net depends_on: backend: condition: service_healthy restart: unless-stopped # SECURITY: Use specific capabilities instead of privileged mode # privileged: true # REMOVED - security risk cap_add: - SYS_RAWIO security_opt: - no-new-privileges:true volumes: - ./alpr-service/dataset:/app/dataset healthcheck: test: [ "CMD", "wget", "-q", "--spider", "http://localhost:5001/health" ] interval: 30s timeout: 10s retries: 3 start_period: 60s logging: driver: "json-file" options: max-size: "20m" max-file: "5" # Frontend Service (React) frontend: build: ./frontend container_name: controlpatente-frontend ports: - "5173:5173" networks: - backend-net restart: unless-stopped volumes: - ./frontend:/app - /app/node_modules environment: - VITE_API_URL= - VITE_ALPR_STREAM_URL= logging: driver: "json-file" options: max-size: "10m" max-file: "3" networks: backend-net: driver: bridge volumes: db_data: