version: '3.9' services: # PostgreSQL Database postgres: image: postgres:14-alpine container_name: marketing_postgres environment: POSTGRES_USER: ${POSTGRES_USER} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} POSTGRES_DB: ${POSTGRES_DB} volumes: - postgres_data:/var/lib/postgresql/data networks: - marketing_network restart: always healthcheck: test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER}"] interval: 10s timeout: 5s retries: 5 # MongoDB for Events mongodb: image: mongo:5-focal container_name: marketing_mongodb environment: MONGO_INITDB_ROOT_USERNAME: ${MONGO_USERNAME:-admin} MONGO_INITDB_ROOT_PASSWORD: ${MONGO_PASSWORD} volumes: - mongodb_data:/data/db networks: - marketing_network restart: always healthcheck: test: echo 'db.runCommand("ping").ok' | mongosh localhost:27017/test --quiet interval: 10s timeout: 5s retries: 5 # Redis for Cache and Queue redis: image: redis:7-alpine container_name: marketing_redis command: redis-server --appendonly yes --requirepass ${REDIS_PASSWORD} volumes: - redis_data:/data networks: - marketing_network restart: always healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 5 # RabbitMQ Message Broker rabbitmq: image: rabbitmq:3-management-alpine container_name: marketing_rabbitmq environment: RABBITMQ_DEFAULT_USER: ${RABBITMQ_DEFAULT_USER} RABBITMQ_DEFAULT_PASS: ${RABBITMQ_DEFAULT_PASS} volumes: - rabbitmq_data:/var/lib/rabbitmq networks: - marketing_network restart: always healthcheck: test: ["CMD", "rabbitmq-diagnostics", "-q", "ping"] interval: 10s timeout: 5s retries: 5 # Elasticsearch (Optional for production) elasticsearch: image: docker.elastic.co/elasticsearch/elasticsearch:8.12.0 container_name: marketing_elasticsearch environment: - discovery.type=single-node - xpack.security.enabled=true - ELASTIC_PASSWORD=${ELASTIC_PASSWORD} - "ES_JAVA_OPTS=-Xms1g -Xmx1g" volumes: - elasticsearch_data:/usr/share/elasticsearch/data networks: - marketing_network restart: always healthcheck: test: ["CMD-SHELL", "curl -s -u elastic:${ELASTIC_PASSWORD} http://localhost:9200/_cluster/health || exit 1"] interval: 30s timeout: 10s retries: 5 # API Gateway Service api-gateway: build: context: ./services/api-gateway dockerfile: Dockerfile container_name: marketing_api_gateway environment: - NODE_ENV=production - REDIS_HOST=redis - REDIS_PASSWORD=${REDIS_PASSWORD} - MONGODB_URI=mongodb://${MONGO_USERNAME}:${MONGO_PASSWORD}@mongodb:27017/marketing_agent?authSource=admin - JWT_SECRET=${JWT_SECRET} - ORCHESTRATOR_URL=http://orchestrator:3001 - CLAUDE_AGENT_URL=http://claude-agent:3002 - GRAMJS_ADAPTER_URL=http://gramjs-adapter:3003 - SAFETY_GUARD_URL=http://safety-guard:3004 - ANALYTICS_URL=http://analytics:3005 - COMPLIANCE_GUARD_URL=http://compliance-guard:3006 - AB_TESTING_URL=http://ab-testing:3007 - TELEGRAM_SYSTEM_URL=${TELEGRAM_SYSTEM_URL} depends_on: redis: condition: service_healthy mongodb: condition: service_healthy networks: - marketing_network restart: always deploy: replicas: 2 resources: limits: cpus: '1' memory: 1G healthcheck: test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:3000/health"] interval: 10s timeout: 5s retries: 5 # Orchestrator Service orchestrator: build: context: ./services/orchestrator dockerfile: Dockerfile container_name: marketing_orchestrator environment: - NODE_ENV=production - MONGODB_URI=mongodb://${MONGO_USERNAME}:${MONGO_PASSWORD}@mongodb:27017/marketing_agent?authSource=admin - REDIS_HOST=redis - REDIS_PASSWORD=${REDIS_PASSWORD} - RABBITMQ_URL=amqp://${RABBITMQ_DEFAULT_USER}:${RABBITMQ_DEFAULT_PASS}@rabbitmq:5672 - JWT_SECRET=${JWT_SECRET} depends_on: mongodb: condition: service_healthy redis: condition: service_healthy rabbitmq: condition: service_healthy networks: - marketing_network restart: always deploy: resources: limits: cpus: '2' memory: 2G healthcheck: test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:3001/health"] interval: 10s timeout: 5s retries: 5 # Claude Agent Service claude-agent: build: context: ./services/claude-agent dockerfile: Dockerfile container_name: marketing_claude_agent environment: - NODE_ENV=production - MONGODB_URI=mongodb://${MONGO_USERNAME}:${MONGO_PASSWORD}@mongodb:27017/marketing_agent?authSource=admin - REDIS_HOST=redis - REDIS_PASSWORD=${REDIS_PASSWORD} - RABBITMQ_URL=amqp://${RABBITMQ_DEFAULT_USER}:${RABBITMQ_DEFAULT_PASS}@rabbitmq:5672 - ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY} depends_on: mongodb: condition: service_healthy redis: condition: service_healthy rabbitmq: condition: service_healthy networks: - marketing_network restart: always deploy: resources: limits: cpus: '2' memory: 4G healthcheck: test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:3002/health"] interval: 10s timeout: 5s retries: 5 # GramJS Adapter Service gramjs-adapter: build: context: ./services/gramjs-adapter dockerfile: Dockerfile container_name: marketing_gramjs_adapter environment: - NODE_ENV=production - MONGODB_URI=mongodb://${MONGO_USERNAME}:${MONGO_PASSWORD}@mongodb:27017/marketing_agent?authSource=admin - REDIS_HOST=redis - REDIS_PASSWORD=${REDIS_PASSWORD} - RABBITMQ_URL=amqp://${RABBITMQ_DEFAULT_USER}:${RABBITMQ_DEFAULT_PASS}@rabbitmq:5672 - TELEGRAM_SYSTEM_API_URL=${TELEGRAM_SYSTEM_URL} depends_on: mongodb: condition: service_healthy redis: condition: service_healthy rabbitmq: condition: service_healthy networks: - marketing_network restart: always deploy: replicas: 2 resources: limits: cpus: '2' memory: 2G healthcheck: test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:3003/health"] interval: 10s timeout: 5s retries: 5 # Safety Guard Service safety-guard: build: context: ./services/safety-guard dockerfile: Dockerfile container_name: marketing_safety_guard environment: - NODE_ENV=production - MONGODB_URI=mongodb://${MONGO_USERNAME}:${MONGO_PASSWORD}@mongodb:27017/marketing_agent?authSource=admin - REDIS_HOST=redis - REDIS_PASSWORD=${REDIS_PASSWORD} - RABBITMQ_URL=amqp://${RABBITMQ_DEFAULT_USER}:${RABBITMQ_DEFAULT_PASS}@rabbitmq:5672 - OPENAI_API_KEY=${OPENAI_API_KEY} - GOOGLE_CLOUD_PROJECT=${GOOGLE_CLOUD_PROJECT} depends_on: mongodb: condition: service_healthy redis: condition: service_healthy rabbitmq: condition: service_healthy networks: - marketing_network restart: always deploy: resources: limits: cpus: '1' memory: 1G healthcheck: test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:3004/health"] interval: 10s timeout: 5s retries: 5 # Analytics Service analytics: build: context: ./services/analytics dockerfile: Dockerfile container_name: marketing_analytics environment: - NODE_ENV=production - MONGODB_URI=mongodb://${MONGO_USERNAME}:${MONGO_PASSWORD}@mongodb:27017/marketing_agent?authSource=admin - REDIS_HOST=redis - REDIS_PASSWORD=${REDIS_PASSWORD} - CLICKHOUSE_HOST=${CLICKHOUSE_HOST:-clickhouse} - ELASTICSEARCH_HOST=elasticsearch:9200 - ELASTIC_PASSWORD=${ELASTIC_PASSWORD} - RABBITMQ_URL=amqp://${RABBITMQ_DEFAULT_USER}:${RABBITMQ_DEFAULT_PASS}@rabbitmq:5672 depends_on: mongodb: condition: service_healthy redis: condition: service_healthy elasticsearch: condition: service_healthy rabbitmq: condition: service_healthy networks: - marketing_network restart: always deploy: resources: limits: cpus: '2' memory: 2G healthcheck: test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:3005/health"] interval: 10s timeout: 5s retries: 5 # Compliance Guard Service compliance-guard: build: context: ./services/compliance-guard dockerfile: Dockerfile container_name: marketing_compliance_guard environment: - NODE_ENV=production - MONGODB_URI=mongodb://${MONGO_USERNAME}:${MONGO_PASSWORD}@mongodb:27017/marketing_agent?authSource=admin - REDIS_HOST=redis - REDIS_PASSWORD=${REDIS_PASSWORD} - RABBITMQ_URL=amqp://${RABBITMQ_DEFAULT_USER}:${RABBITMQ_DEFAULT_PASS}@rabbitmq:5672 - JWT_SECRET=${JWT_SECRET} - ENCRYPTION_KEY=${ENCRYPTION_KEY} depends_on: mongodb: condition: service_healthy redis: condition: service_healthy rabbitmq: condition: service_healthy networks: - marketing_network restart: always deploy: resources: limits: cpus: '1' memory: 1G healthcheck: test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:3006/health"] interval: 10s timeout: 5s retries: 5 # A/B Testing Service ab-testing: build: context: ./services/ab-testing dockerfile: Dockerfile container_name: marketing_ab_testing environment: - NODE_ENV=production - MONGODB_URI=mongodb://${MONGO_USERNAME}:${MONGO_PASSWORD}@mongodb:27017/marketing_agent?authSource=admin - REDIS_HOST=redis - REDIS_PASSWORD=${REDIS_PASSWORD} - RABBITMQ_URL=amqp://${RABBITMQ_DEFAULT_USER}:${RABBITMQ_DEFAULT_PASS}@rabbitmq:5672 depends_on: mongodb: condition: service_healthy redis: condition: service_healthy rabbitmq: condition: service_healthy networks: - marketing_network restart: always deploy: resources: limits: cpus: '1' memory: 1G healthcheck: test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:3007/health"] interval: 10s timeout: 5s retries: 5 # Nginx Reverse Proxy nginx: image: nginx:alpine container_name: marketing_nginx ports: - "80:80" - "443:443" volumes: - ./infrastructure/nginx/nginx.prod.conf:/etc/nginx/nginx.conf - ./infrastructure/nginx/conf.d:/etc/nginx/conf.d - ./infrastructure/ssl:/etc/ssl depends_on: api-gateway: condition: service_healthy networks: - marketing_network restart: always healthcheck: test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost/health"] interval: 10s timeout: 5s retries: 5 # Prometheus prometheus: image: prom/prometheus:latest container_name: marketing_prometheus command: - '--config.file=/etc/prometheus/prometheus.yml' - '--storage.tsdb.path=/prometheus' - '--storage.tsdb.retention.time=30d' volumes: - ./infrastructure/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml - prometheus_data:/prometheus networks: - marketing_network restart: always # Grafana grafana: image: grafana/grafana:latest container_name: marketing_grafana environment: - GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_ADMIN_PASSWORD} - GF_USERS_ALLOW_SIGN_UP=false - GF_INSTALL_PLUGINS=grafana-clock-panel,grafana-simple-json-datasource volumes: - grafana_data:/var/lib/grafana - ./infrastructure/grafana/provisioning:/etc/grafana/provisioning depends_on: - prometheus networks: - marketing_network restart: always volumes: postgres_data: driver: local mongodb_data: driver: local redis_data: driver: local rabbitmq_data: driver: local elasticsearch_data: driver: local prometheus_data: driver: local grafana_data: driver: local networks: marketing_network: driver: bridge ipam: config: - subnet: 172.20.0.0/16