services: # MinIO S3-compatible storage minio: image: minio/minio:latest container_name: minio ports: - "9000:9000" - "9001:9001" environment: MINIO_ROOT_USER: admin MINIO_ROOT_PASSWORD: password123 command: server /data --console-address ":9001" volumes: - minio_data:/data healthcheck: test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"] interval: 30s timeout: 20s retries: 3 # MinIO bucket initialization minio-init: image: minio/mc:latest container_name: minio-init depends_on: minio: condition: service_healthy entrypoint: > /bin/sh -c " /usr/bin/mc alias set minio http://minio:9000 admin password123; /usr/bin/mc mb --ignore-existing minio/warehouse; /usr/bin/mc mb --ignore-existing minio/checkpoints; echo 'MinIO buckets created successfully'; " mariadb: image: mariadb:10.6.14 container_name: mariadb environment: MYSQL_ROOT_PASSWORD: rootpassword volumes: - ./sql/mariadb.cnf:/etc/mysql/mariadb.conf.d/mariadb.cnf - ./sql/init.sql:/docker-entrypoint-initdb.d/init.sql ports: - "3306:3306" # Flink Job Manager with custom image jobmanager: build: . container_name: flink-jobmanager ports: - "8081:8081" environment: - JOB_MANAGER_RPC_ADDRESS=jobmanager volumes: # Only mount configuration, no JARs needed - ./conf/flink-conf.yaml:/opt/flink/conf/flink-conf.yaml - ./sql:/opt/flink/sql command: jobmanager depends_on: - minio-init healthcheck: test: ["CMD-SHELL", "curl -f http://localhost:8081/ || exit 1"] interval: 30s timeout: 10s retries: 5 # Flink Task Manager taskmanager: build: . container_name: flink-taskmanager environment: - JOB_MANAGER_RPC_ADDRESS=jobmanager - TASK_MANAGER_NUMBER_OF_TASK_SLOTS=4 volumes: - ./conf/flink-conf.yaml:/opt/flink/conf/flink-conf.yaml - ./sql:/opt/flink/sql command: taskmanager depends_on: jobmanager: condition: service_healthy scale: 1 # --- DuckDB CLI (optional for manual queries) --- duckdb: image: python:3.11-slim container_name: duckdb depends_on: jobmanager: condition: service_healthy working_dir: /workspace environment: - S3_ENDPOINT=http://minio:9000 - S3_ACCESS_KEY=admin - S3_SECRET_KEY=password123 volumes: - ./duckdb:/workspace command: ["sleep", "infinity"] init: true # --- Rill (Real-time Analytics Dashboard) --- rill: image: rilldata/rill:latest container_name: rill user: "1000:1000" depends_on: jobmanager: condition: service_healthy ports: - "3000:9009" environment: - RILL_LOG_LEVEL=info - RILL_ADMIN_DATABASE_DRIVER=duckdb - RILL_ADMIN_DATABASE_DSN=/data/rill.db - RILL_RUNTIME_HOST=0.0.0.0 # DuckDB S3 configuration for MinIO access - AWS_REGION=us-east-1 - AWS_DEFAULT_REGION=us-east-1 - AWS_S3_ENDPOINT=minio:9000 - AWS_S3_USE_SSL=false - AWS_S3_URL_STYLE=path - AWS_ACCESS_KEY_ID=admin - AWS_SECRET_ACCESS_KEY=password123 volumes: - ./rill:/app - rill_data:/data - ./duckdb:/shared working_dir: /app command: ["start", ".", "--verbose", "--no-open", "--port", "9009", "--interactive=false"] networks: - flink-network deploy: resources: limits: cpus: '2.0' memory: 6G reservations: cpus: '1.0' memory: 2G # --- Rill Catalog Patcher (automates catalog prefix updates + periodic refresh) --- rill-patcher: image: alpine:latest container_name: rill-patcher depends_on: rill: condition: service_started volumes: - ./rill:/app - ./rill-patcher.sh:/rill-patcher.sh command: ["sh", "-c", "apk add --no-cache curl jq && /rill-patcher.sh"] networks: - flink-network restart: unless-stopped # --- Soda (CLI container; you exec scans against DuckDB) --- soda: image: python:3.11-slim container_name: soda depends_on: jobmanager: condition: service_healthy working_dir: /soda environment: - S3_ENDPOINT=http://minio:9000 - S3_ACCESS_KEY=admin - S3_SECRET_KEY=password123 volumes: - ./soda:/soda command: ["sleep", "infinity"] init: true volumes: minio_data: driver: local rill_data: driver: local networks: default: name: flink-paimon-network