Cinematch / docker-compose.yml
Amit-kr26's picture
feat: MLOps eval, A/B testing, DLQ, WebSocket, cold-start fallback
3fc8ccc
Raw
History Blame Contribute Delete
4.54 kB
services:
kafka:
image: apache/kafka:3.9.0
ports:
- "9092:9092"
environment:
KAFKA_NODE_ID: "1"
KAFKA_PROCESS_ROLES: "broker,controller"
KAFKA_CONTROLLER_QUORUM_VOTERS: "1@kafka:9093"
KAFKA_LISTENERS: "PLAINTEXT://:9092,CONTROLLER://:9093"
KAFKA_ADVERTISED_LISTENERS: "PLAINTEXT://kafka:9092"
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: "CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT"
KAFKA_CONTROLLER_LISTENER_NAMES: "CONTROLLER"
KAFKA_INTER_BROKER_LISTENER_NAME: "PLAINTEXT"
CLUSTER_ID: "MkU3OEVBNTcwNTJENDM2Qk"
KAFKA_AUTO_CREATE_TOPICS_ENABLE: "true"
KAFKA_NUM_PARTITIONS: "3"
healthcheck:
test: ["CMD-SHELL", "/opt/kafka/bin/kafka-topics.sh --bootstrap-server localhost:9092 --list"]
interval: 10s
timeout: 5s
retries: 15
deploy:
resources:
limits:
memory: 1G
mlflow:
image: python:3.12-slim
command: >
bash -c "pip install mlflow>=2.13 --quiet --no-cache-dir &&
mlflow server --backend-store-uri file:///mlruns --default-artifact-root file:///mlruns --host 0.0.0.0 --port 5000"
ports:
- "5000:5000"
volumes:
- ./data/mlruns:/mlruns
spark:
build: ./services/spark-jobs
command: >
bash -c "until [ -f /data/ml-1m/ratings.dat ]; do echo 'Waiting for bootstrap data...'; sleep 5; done && python streaming.py"
environment:
SPARK_MASTER: "local[*]"
REDIS_URL: "redis://redis:6379"
POSTGRES_URL: "postgresql://recsys:recsys@postgres:5432/recsys"
KAFKA_BOOTSTRAP_SERVERS: "kafka:9092"
DATA_DIR: "/data"
CHECKPOINT_DIR: "/tmp/spark-checkpoint"
MLFLOW_TRACKING_URI: "http://mlflow:5000"
PYTHONUNBUFFERED: "1"
volumes:
- ./data:/data
- spark-checkpoint:/tmp/spark-checkpoint
depends_on:
kafka: { condition: service_healthy }
redis: { condition: service_healthy }
postgres: { condition: service_healthy }
deploy:
resources:
limits:
memory: 2G
restart: on-failure
event-simulator:
build: ./services/event-simulator
environment:
KAFKA_BOOTSTRAP_SERVERS: "kafka:9092"
DATA_DIR: "/data"
EVENT_RATE: "5"
volumes:
- ./data:/data
depends_on:
kafka: { condition: service_healthy }
restart: on-failure
api:
build: ./services/api
ports:
- "8000:8000"
environment:
REDIS_URL: "redis://redis:6379"
POSTGRES_URL: "postgresql://recsys:recsys@postgres:5432/recsys"
KAFKA_BOOTSTRAP_SERVERS: "kafka:9092"
depends_on:
redis: { condition: service_healthy }
postgres: { condition: service_healthy }
kafka: { condition: service_healthy }
healthcheck:
test: ["CMD-SHELL", "python3 -c \"import urllib.request; urllib.request.urlopen('http://localhost:8000/health')\""]
interval: 10s
timeout: 5s
retries: 5
restart: on-failure
redis:
image: redis:7-alpine
ports:
- "6379:6379"
command: redis-server --save 60 1 --appendonly yes
volumes:
- redis-data:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 5s
timeout: 3s
retries: 10
postgres:
image: postgres:16-alpine
environment:
POSTGRES_USER: ${POSTGRES_USER:-recsys}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-recsys}
POSTGRES_DB: ${POSTGRES_DB:-recsys}
ports:
- "5432:5432"
volumes:
- postgres-data:/var/lib/postgresql/data
- ./services/api/schema.sql:/docker-entrypoint-initdb.d/schema.sql
healthcheck:
test: ["CMD-SHELL", "pg_isready -U recsys"]
interval: 5s
timeout: 3s
retries: 10
frontend:
build: ./services/frontend
ports:
- "3000:80"
depends_on:
api: { condition: service_healthy }
prometheus:
image: prom/prometheus:v2.51.0
ports:
- "9090:9090"
volumes:
- ./infra/prometheus.yml:/etc/prometheus/prometheus.yml:ro
grafana:
image: grafana/grafana:10.4.3
ports:
- "3001:3000"
environment:
GF_SECURITY_ADMIN_PASSWORD: ${GRAFANA_ADMIN_PASSWORD:-admin}
GF_AUTH_ANONYMOUS_ENABLED: "true"
GF_AUTH_ANONYMOUS_ORG_ROLE: Viewer
volumes:
- grafana-data:/var/lib/grafana
- ./infra/grafana/datasources:/etc/grafana/provisioning/datasources:ro
- ./infra/grafana/dashboards:/etc/grafana/provisioning/dashboards:ro
volumes:
postgres-data:
grafana-data:
spark-checkpoint:
redis-data: