# Trino conceptual-learning cluster: # 1 coordinator + 2 workers -> proves distributed (MPP) execution: stages / tasks / splits # mysql -> a second catalog, for cross-catalog federation demos # minio + iceberg-rest -> S3-compatible lakehouse for the Iceberg module # jupyter -> notebook client driving Trino via the python `trino` client # # The tpch / tpcds catalogs need NO external data — the connectors generate data in-engine, # which is what most concept notebooks (plans, joins, CBO) run against. services: trino-coordinator: image: trinodb/trino:${TRINO_VERSION} container_name: trino-coordinator ports: # Host port is overridable: spark-learn's Spark master also uses 8080, so set # TRINO_UI_PORT (e.g. 8088) in .env to run both repos at once. Container stays 8080. - "${TRINO_UI_PORT:-8080}:8080" # Web UI + REST/JDBC client endpoint mem_limit: 3g environment: MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD} MINIO_ROOT_USER: ${MINIO_ROOT_USER} MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD} volumes: - ./trino/coordinator/config.properties:/etc/trino/config.properties:ro - ./trino/jvm.config:/etc/trino/jvm.config:ro - ./trino/catalog:/etc/trino/catalog:ro trino-worker-1: image: trinodb/trino:${TRINO_VERSION} container_name: trino-worker-1 mem_limit: 3g depends_on: - trino-coordinator environment: MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD} MINIO_ROOT_USER: ${MINIO_ROOT_USER} MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD} volumes: - ./trino/worker/config.properties:/etc/trino/config.properties:ro - ./trino/jvm.config:/etc/trino/jvm.config:ro - ./trino/catalog:/etc/trino/catalog:ro trino-worker-2: image: trinodb/trino:${TRINO_VERSION} container_name: trino-worker-2 mem_limit: 3g depends_on: - trino-coordinator environment: MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD} MINIO_ROOT_USER: ${MINIO_ROOT_USER} MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD} volumes: - ./trino/worker/config.properties:/etc/trino/config.properties:ro - ./trino/jvm.config:/etc/trino/jvm.config:ro - ./trino/catalog:/etc/trino/catalog:ro mysql: image: mysql:8 container_name: trino-mysql ports: - "3306:3306" environment: MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD} MYSQL_DATABASE: ${MYSQL_DATABASE} volumes: - mysql-data:/var/lib/mysql minio: image: minio/minio:latest container_name: trino-minio command: server /data --console-address ":9001" ports: - "9000:9000" # S3 API - "9001:9001" # Web console environment: MINIO_ROOT_USER: ${MINIO_ROOT_USER} MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD} volumes: - minio-data:/data # One-shot: create the `warehouse` bucket the Iceberg REST catalog writes into. minio-init: image: minio/mc:latest container_name: trino-minio-init depends_on: - minio entrypoint: > /bin/sh -c " until mc alias set local http://minio:9000 ${MINIO_ROOT_USER} ${MINIO_ROOT_PASSWORD}; do sleep 1; done; mc mb -p local/warehouse || true; exit 0; " # Iceberg REST catalog (metadata) backed by MinIO (data files). iceberg-rest: image: tabulario/iceberg-rest:latest container_name: trino-iceberg-rest ports: - "8181:8181" depends_on: - minio environment: AWS_ACCESS_KEY_ID: ${MINIO_ROOT_USER} AWS_SECRET_ACCESS_KEY: ${MINIO_ROOT_PASSWORD} AWS_REGION: us-east-1 CATALOG_WAREHOUSE: s3://warehouse/ CATALOG_IO__IMPL: org.apache.iceberg.aws.s3.S3FileIO CATALOG_S3_ENDPOINT: http://minio:9000 CATALOG_S3_PATH__STYLE__ACCESS: "true" jupyter: build: context: . dockerfile: docker/jupyter.Dockerfile container_name: trino-jupyter ports: # Overridable like the Trino UI port — spark-learn's Jupyter also uses 8888. - "${JUPYTER_PORT:-8888}:8888" environment: JUPYTER_TOKEN: ${JUPYTER_TOKEN} depends_on: - trino-coordinator volumes: - ./notebooks:/home/jovyan/work - ./data:/home/jovyan/data volumes: mysql-data: minio-data: