# docker-compose.yml - Development Environment services: # Message Broker rabbitmq: image: rabbitmq:3-management-alpine container_name: bakery-rabbitmq hostname: rabbitmq ports: - "5672:5672" - "15672:15672" environment: - RABBITMQ_DEFAULT_USER=bakery - RABBITMQ_DEFAULT_PASS=forecast123 - RABBITMQ_DEFAULT_VHOST=/ volumes: - rabbitmq_data:/var/lib/rabbitmq networks: - bakery-network healthcheck: test: ["CMD", "rabbitmq-diagnostics", "ping"] interval: 30s timeout: 10s retries: 3 # Cache & Session Store redis: image: redis:7-alpine container_name: bakery-redis ports: - "6379:6379" volumes: - redis_data:/data networks: - bakery-network command: redis-server --appendonly yes healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 30s timeout: 10s retries: 3 # Auth Service Database auth-db: image: postgres:15-alpine container_name: bakery-auth-db environment: - POSTGRES_DB=auth_db - POSTGRES_USER=auth_user - POSTGRES_PASSWORD=auth_pass123 volumes: - auth_db_data:/var/lib/postgresql/data ports: - "5432:5432" networks: - bakery-network healthcheck: test: ["CMD-SHELL", "pg_isready -U auth_user -d auth_db"] interval: 30s timeout: 10s retries: 3 # Training Service Database training-db: image: postgres:15-alpine container_name: bakery-training-db environment: - POSTGRES_DB=training_db - POSTGRES_USER=training_user - POSTGRES_PASSWORD=training_pass123 volumes: - training_db_data:/var/lib/postgresql/data ports: - "5433:5432" networks: - bakery-network healthcheck: test: ["CMD-SHELL", "pg_isready -U training_user -d training_db"] interval: 30s timeout: 10s retries: 3 # Forecasting Service Database forecasting-db: image: postgres:15-alpine container_name: bakery-forecasting-db environment: - POSTGRES_DB=forecasting_db - POSTGRES_USER=forecasting_user - POSTGRES_PASSWORD=forecasting_pass123 volumes: - forecasting_db_data:/var/lib/postgresql/data ports: - "5434:5432" networks: - bakery-network healthcheck: test: ["CMD-SHELL", "pg_isready -U forecasting_user -d forecasting_db"] interval: 30s timeout: 10s retries: 3 # Data Service Database data-db: image: postgres:15-alpine container_name: bakery-data-db environment: - POSTGRES_DB=data_db - POSTGRES_USER=data_user - POSTGRES_PASSWORD=data_pass123 volumes: - data_db_data:/var/lib/postgresql/data ports: - "5435:5432" networks: - bakery-network healthcheck: test: ["CMD-SHELL", "pg_isready -U data_user -d data_db"] interval: 30s timeout: 10s retries: 3 # Tenant Service Database tenant-db: image: postgres:15-alpine container_name: bakery-tenant-db environment: - POSTGRES_DB=tenant_db - POSTGRES_USER=tenant_user - POSTGRES_PASSWORD=tenant_pass123 volumes: - tenant_db_data:/var/lib/postgresql/data ports: - "5436:5432" networks: - bakery-network healthcheck: test: ["CMD-SHELL", "pg_isready -U tenant_user -d tenant_db"] interval: 30s timeout: 10s retries: 3 # Notification Service Database notification-db: image: postgres:15-alpine container_name: bakery-notification-db environment: - POSTGRES_DB=notification_db - POSTGRES_USER=notification_user - POSTGRES_PASSWORD=notification_pass123 volumes: - notification_db_data:/var/lib/postgresql/data ports: - "5437:5432" networks: - bakery-network healthcheck: test: ["CMD-SHELL", "pg_isready -U notification_user -d notification_db"] interval: 30s timeout: 10s retries: 3 # Authentication Service auth-service: build: context: ./services/auth dockerfile: Dockerfile container_name: bakery-auth-service environment: - DATABASE_URL=postgresql+asyncpg://auth_user:auth_pass123@auth-db:5432/auth_db - REDIS_URL=redis://redis:6379/0 - JWT_SECRET_KEY=your-super-secret-jwt-key-change-in-production - JWT_ACCESS_TOKEN_EXPIRE_MINUTES=30 - JWT_REFRESH_TOKEN_EXPIRE_DAYS=7 - RABBITMQ_URL=amqp://bakery:forecast123@rabbitmq:5672/ - SERVICE_NAME=auth-service - SERVICE_VERSION=1.0.0 ports: - "8001:8000" depends_on: auth-db: condition: service_healthy redis: condition: service_healthy rabbitmq: condition: service_healthy networks: - bakery-network volumes: - ./services/auth:/app healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8000/health"] interval: 30s timeout: 10s retries: 3 # Training Service training-service: build: context: ./services/training dockerfile: Dockerfile container_name: bakery-training-service environment: - DATABASE_URL=postgresql+asyncpg://training_user:training_pass123@training-db:5432/training_db - REDIS_URL=redis://redis:6379/1 - RABBITMQ_URL=amqp://bakery:forecast123@rabbitmq:5672/ - AUTH_SERVICE_URL=http://auth-service:8000 - DATA_SERVICE_URL=http://data-service:8000 - SERVICE_NAME=training-service - SERVICE_VERSION=1.0.0 ports: - "8002:8000" depends_on: training-db: condition: service_healthy redis: condition: service_healthy rabbitmq: condition: service_healthy auth-service: condition: service_healthy networks: - bakery-network volumes: - ./services/training:/app healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8000/health"] interval: 30s timeout: 10s retries: 3 # Forecasting Service forecasting-service: build: context: ./services/forecasting dockerfile: Dockerfile container_name: bakery-forecasting-service environment: - DATABASE_URL=postgresql+asyncpg://forecasting_user:forecasting_pass123@forecasting-db:5432/forecasting_db - REDIS_URL=redis://redis:6379/2 - RABBITMQ_URL=amqp://bakery:forecast123@rabbitmq:5672/ - AUTH_SERVICE_URL=http://auth-service:8000 - TRAINING_SERVICE_URL=http://training-service:8000 - DATA_SERVICE_URL=http://data-service:8000 - SERVICE_NAME=forecasting-service - SERVICE_VERSION=1.0.0 ports: - "8003:8000" depends_on: forecasting-db: condition: service_healthy redis: condition: service_healthy rabbitmq: condition: service_healthy auth-service: condition: service_healthy networks: - bakery-network volumes: - ./services/forecasting:/app healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8000/health"] interval: 30s timeout: 10s retries: 3 # Data Service data-service: build: context: ./services/data dockerfile: Dockerfile container_name: bakery-data-service environment: - DATABASE_URL=postgresql+asyncpg://data_user:data_pass123@data-db:5432/data_db - REDIS_URL=redis://redis:6379/3 - RABBITMQ_URL=amqp://bakery:forecast123@rabbitmq:5672/ - AUTH_SERVICE_URL=http://auth-service:8000 - AEMET_API_KEY=your-aemet-api-key-here - MADRID_OPENDATA_API_KEY=your-madrid-opendata-key-here - SERVICE_NAME=data-service - SERVICE_VERSION=1.0.0 ports: - "8004:8000" depends_on: data-db: condition: service_healthy redis: condition: service_healthy rabbitmq: condition: service_healthy auth-service: condition: service_healthy networks: - bakery-network volumes: - ./services/data:/app healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8000/health"] interval: 30s timeout: 10s retries: 3 # Tenant Service tenant-service: build: context: ./services/tenant dockerfile: Dockerfile container_name: bakery-tenant-service environment: - DATABASE_URL=postgresql+asyncpg://tenant_user:tenant_pass123@tenant-db:5432/tenant_db - REDIS_URL=redis://redis:6379/4 - RABBITMQ_URL=amqp://bakery:forecast123@rabbitmq:5672/ - AUTH_SERVICE_URL=http://auth-service:8000 - SERVICE_NAME=tenant-service - SERVICE_VERSION=1.0.0 ports: - "8005:8000" depends_on: tenant-db: condition: service_healthy redis: condition: service_healthy rabbitmq: condition: service_healthy auth-service: condition: service_healthy networks: - bakery-network volumes: - ./services/tenant:/app healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8000/health"] interval: 30s timeout: 10s retries: 3 # Notification Service notification-service: build: context: ./services/notification dockerfile: Dockerfile container_name: bakery-notification-service environment: - DATABASE_URL=postgresql+asyncpg://notification_user:notification_pass123@notification-db:5432/notification_db - REDIS_URL=redis://redis:6379/5 - RABBITMQ_URL=amqp://bakery:forecast123@rabbitmq:5672/ - AUTH_SERVICE_URL=http://auth-service:8000 - SMTP_HOST=smtp.gmail.com - SMTP_PORT=587 - SMTP_USER=your-email@gmail.com - SMTP_PASSWORD=your-email-password - WHATSAPP_API_KEY=your-whatsapp-api-key - SERVICE_NAME=notification-service - SERVICE_VERSION=1.0.0 ports: - "8006:8000" depends_on: notification-db: condition: service_healthy redis: condition: service_healthy rabbitmq: condition: service_healthy auth-service: condition: service_healthy networks: - bakery-network volumes: - ./services/notification:/app healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8000/health"] interval: 30s timeout: 10s retries: 3 # API Gateway gateway: build: context: ./gateway dockerfile: Dockerfile container_name: bakery-gateway environment: - REDIS_URL=redis://redis:6379/6 - AUTH_SERVICE_URL=http://auth-service:8000 - TRAINING_SERVICE_URL=http://training-service:8000 - FORECASTING_SERVICE_URL=http://forecasting-service:8000 - DATA_SERVICE_URL=http://data-service:8000 - TENANT_SERVICE_URL=http://tenant-service:8000 - NOTIFICATION_SERVICE_URL=http://notification-service:8000 - CORS_ORIGINS=http://localhost:3000,http://localhost:3001 - SERVICE_NAME=gateway - SERVICE_VERSION=1.0.0 ports: - "8000:8000" depends_on: auth-service: condition: service_healthy training-service: condition: service_healthy forecasting-service: condition: service_healthy data-service: condition: service_healthy tenant-service: condition: service_healthy notification-service: condition: service_healthy networks: - bakery-network volumes: - ./gateway:/app healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8000/health"] interval: 30s timeout: 10s retries: 3 # Dashboard Frontend dashboard: build: context: ./frontend dockerfile: Dockerfile.dev container_name: bakery-dashboard environment: - REACT_APP_API_URL=http://localhost:8000 - REACT_APP_WS_URL=ws://localhost:8000 - CHOKIDAR_USEPOLLING=true ports: - "3000:3000" depends_on: - gateway networks: - bakery-network volumes: - ./frontend:/app - /app/node_modules # Monitoring - Prometheus prometheus: image: prom/prometheus:latest container_name: bakery-prometheus ports: - "9090:9090" volumes: - ./infrastructure/monitoring/prometheus:/etc/prometheus - 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' - '--web.enable-lifecycle' networks: - bakery-network # Monitoring - Grafana grafana: image: grafana/grafana:latest container_name: bakery-grafana ports: - "3002:3000" environment: - GF_SECURITY_ADMIN_PASSWORD=admin123 volumes: - grafana_data:/var/lib/grafana - ./infrastructure/monitoring/grafana:/etc/grafana/provisioning depends_on: - prometheus networks: - bakery-network # Log Aggregation - ELK Stack elasticsearch: image: elasticsearch:8.8.0 container_name: bakery-elasticsearch environment: - discovery.type=single-node - xpack.security.enabled=false - "ES_JAVA_OPTS=-Xms512m -Xmx512m" ports: - "9200:9200" volumes: - elasticsearch_data:/usr/share/elasticsearch/data networks: - bakery-network logstash: image: logstash:8.8.0 container_name: bakery-logstash volumes: - ./infrastructure/monitoring/logstash:/usr/share/logstash/pipeline ports: - "5000:5000" depends_on: - elasticsearch networks: - bakery-network kibana: image: kibana:8.8.0 container_name: bakery-kibana environment: - ELASTICSEARCH_HOSTS=http://elasticsearch:9200 ports: - "5601:5601" depends_on: - elasticsearch networks: - bakery-network volumes: rabbitmq_data: redis_data: auth_db_data: training_db_data: forecasting_db_data: data_db_data: tenant_db_data: notification_db_data: prometheus_data: grafana_data: elasticsearch_data: networks: bakery-network: driver: bridge