version: '3.8' services: # Redis cache for translations redis: image: redis:7-alpine container_name: vibeon-translation-cache restart: unless-stopped ports: - "6379:6379" volumes: - redis-data:/data command: redis-server --appendonly yes --maxmemory 2gb --maxmemory-policy lru networks: - translation-net # Translation API server (multiple instances for load balancing) translation-api-1: build: context: . dockerfile: Dockerfile.ml container_name: vibeon-translation-api-1 restart: unless-stopped ports: - "8081:8080" environment: - NODE_ENV=production - REDIS_URL=redis://redis:6379 - MODEL_PATH=/models - WORKERS=4 - CUDA_VISIBLE_DEVICES=0 volumes: - ./models:/models:ro - ./logs:/logs deploy: resources: reservations: devices: - driver: nvidia count: 1 capabilities: [gpu] depends_on: - redis networks: - translation-net translation-api-2: build: context: . dockerfile: Dockerfile.ml container_name: vibeon-translation-api-2 restart: unless-stopped ports: - "8082:8080" environment: - NODE_ENV=production - REDIS_URL=redis://redis:6379 - MODEL_PATH=/models - WORKERS=4 - CUDA_VISIBLE_DEVICES=1 volumes: - ./models:/models:ro - ./logs:/logs deploy: resources: reservations: devices: - driver: nvidia count: 1 capabilities: [gpu] depends_on: - redis networks: - translation-net # Nginx load balancer nginx: image: nginx:alpine container_name: vibeon-translation-lb restart: unless-stopped ports: - "8080:80" volumes: - ./nginx.conf:/etc/nginx/nginx.conf:ro depends_on: - translation-api-1 - translation-api-2 networks: - translation-net # Model updater service (runs periodically) model-updater: build: context: . dockerfile: Dockerfile.updater container_name: vibeon-model-updater restart: unless-stopped environment: - UPDATE_INTERVAL=3600 # 1 hour - MODEL_REGISTRY=s3://vibeon-models - AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID} - AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY} volumes: - ./models:/models - ./config:/config:ro networks: - translation-net # Prometheus monitoring prometheus: image: prom/prometheus:latest container_name: vibeon-prometheus restart: unless-stopped ports: - "9090:9090" volumes: - ./monitoring/prometheus.yml:/etc/prometheus/prometheus.yml:ro - prometheus-data:/prometheus command: - '--config.file=/etc/prometheus/prometheus.yml' - '--storage.tsdb.path=/prometheus' - '--web.console.libraries=/usr/share/prometheus/console_libraries' - '--web.console.templates=/usr/share/prometheus/consoles' networks: - translation-net # Grafana dashboards grafana: image: grafana/grafana:latest container_name: vibeon-grafana restart: unless-stopped ports: - "3000:3000" environment: - GF_SECURITY_ADMIN_PASSWORD=admin - GF_USERS_ALLOW_SIGN_UP=false volumes: - grafana-data:/var/lib/grafana - ./monitoring/grafana/dashboards:/etc/grafana/provisioning/dashboards - ./monitoring/grafana/datasources:/etc/grafana/provisioning/datasources depends_on: - prometheus networks: - translation-net # Jupyter notebook for experimentation jupyter: build: context: . dockerfile: Dockerfile.jupyter container_name: vibeon-ml-notebook restart: unless-stopped ports: - "8888:8888" environment: - JUPYTER_ENABLE_LAB=yes volumes: - ./notebooks:/home/jovyan/work - ./models:/home/jovyan/models:ro - ./data:/home/jovyan/data deploy: resources: reservations: devices: - driver: nvidia count: 1 capabilities: [gpu] networks: - translation-net volumes: redis-data: prometheus-data: grafana-data: networks: translation-net: driver: bridge