name: 'hive'

networks:
  stack:
    name: hive

services:
  db:
    image: postgres:16.4-alpine
    environment:
      POSTGRES_DB: '${POSTGRES_DB}'
      POSTGRES_USER: '${POSTGRES_USER}'
      POSTGRES_PASSWORD: '${POSTGRES_PASSWORD}'
      PGDATA: /var/lib/postgresql/data
    healthcheck:
      test: ['CMD-SHELL', 'pg_isready -d $${POSTGRES_DB} -U $${POSTGRES_USER}']
      interval: 5s
      timeout: 5s
      retries: 6
    networks:
      - 'stack'
    volumes:
      - ./.hive/postgres:/var/lib/postgresql/data

  clickhouse:
    image: clickhouse/clickhouse-server:24.8-alpine
    healthcheck:
      test: ['CMD', 'wget', '--spider', '-q', 'http://0.0.0.0:8123/ping']
      interval: 5s
      timeout: 5s
      retries: 6
      start_period: 10s
    environment:
      CLICKHOUSE_USER: '${CLICKHOUSE_USER}'
      CLICKHOUSE_PASSWORD: '${CLICKHOUSE_PASSWORD}'
    networks:
      - 'stack'
    volumes:
      - ./.hive/clickhouse/db:/var/lib/clickhouse

  broker:
    image: redpandadata/redpanda:v23.3.21
    hostname: broker
    networks:
      - 'stack'
    ports:
      - '0.0.0.0:9092:9092'
      - '0.0.0.0:9644:9644'
    command:
      - redpanda
      - start
      - --smp
      - '1'
      - --set redpanda.empty_seed_starts_cluster=false
      - --seeds "redpanda-1:33145"
      - --kafka-addr
      - PLAINTEXT://0.0.0.0:29092,OUTSIDE://0.0.0.0:9092
      - --advertise-kafka-addr
      - PLAINTEXT://broker:29092,OUTSIDE://localhost:9092
      - --pandaproxy-addr
      - PLAINTEXT://0.0.0.0:27082,OUTSIDE://0.0.0.0:7082
      - --advertise-pandaproxy-addr
      - PLAINTEXT://broker:27082,OUTSIDE://localhost:7082
      - --advertise-rpc-addr redpanda-1:33145
    mem_limit: 300m
    mem_reservation: 100m
    healthcheck:
      test: 'curl -f http://localhost:9644/public_metrics'
      interval: 3s
      timeout: 3s
      retries: 6
      start_period: 5s
    volumes:
      - ./.hive/broker/db:/var/lib/redpanda/data

  redis:
    image: bitnamilegacy/redis:7.4.2
    networks:
      - 'stack'
    healthcheck:
      test: ['CMD', 'redis-cli', 'ping']
      interval: 5s
      timeout: 10s
      retries: 6
      start_period: 5s
    environment:
      REDIS_PASSWORD: '${REDIS_PASSWORD}'
      REDIS_DISABLE_COMMANDS: 'FLUSHDB,FLUSHALL'
    volumes:
      - './.hive/redis/db:/bitnami/redis/data'

  s3:
    image: quay.io/minio/minio:RELEASE.2025-09-07T16-13-09Z
    command: server /data --console-address ":9001"
    ports:
      - '9000:9000'
      - '9001:9001'
    networks:
      - 'stack'
    healthcheck:
      test: ['CMD', 'curl', '-f', 'http://localhost:9000/minio/health/live']
      interval: 30s
      timeout: 20s
      retries: 3
    environment:
      MINIO_ROOT_USER: ${MINIO_ROOT_USER}
      MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD}
    volumes:
      - './.hive/minio/db:/data'

  s3_provision_buckets:
    image: quay.io/minio/mc:RELEASE.2025-08-13T08-35-41Z
    depends_on:
      s3:
        condition: service_healthy
    networks:
      - 'stack'
    entrypoint: >
      /bin/sh -c " /usr/bin/mc alias set myminio http://s3:9000 ${MINIO_ROOT_USER}
      ${MINIO_ROOT_PASSWORD}; /usr/bin/mc ls myminio/artifacts >/dev/null 2>&1 || /usr/bin/mc mb
      myminio/artifacts; /usr/bin/mc ls myminio/audit-logs >/dev/null 2>&1 || /usr/bin/mc mb
      myminio/audit-logs; exit 0"

  s3_reverse_proxy:
    image: caddy:2.9.1-alpine
    depends_on:
      s3:
        condition: service_healthy
    networks:
      - 'stack'
    ports:
      - '8083:8083'
    command: caddy reverse-proxy --from :8083 --to s3:9000 --change-host-header

  migrations:
    image: '${DOCKER_REGISTRY}storage${DOCKER_TAG}'
    networks:
      - 'stack'
    depends_on:
      clickhouse:
        condition: service_healthy
      db:
        condition: service_healthy
    environment:
      MIGRATOR: 'up'
      CLICKHOUSE_MIGRATOR: 'up'
      POSTGRES_HOST: db
      POSTGRES_PORT: 5432
      POSTGRES_DB: '${POSTGRES_DB}'
      POSTGRES_USER: '${POSTGRES_USER}'
      POSTGRES_PASSWORD: '${POSTGRES_PASSWORD}'
      CLICKHOUSE_PROTOCOL: 'http'
      CLICKHOUSE_HOST: 'clickhouse'
      CLICKHOUSE_PORT: '8123'
      CLICKHOUSE_USERNAME: '${CLICKHOUSE_USER}'
      CLICKHOUSE_PASSWORD: '${CLICKHOUSE_PASSWORD}'
      CLICKHOUSE_TTL_TABLES: '${CLICKHOUSE_TTL_TABLES:-}'
      CLICKHOUSE_TTL_DAILY_MV_TABLES: '${CLICKHOUSE_TTL_DAILY_MV_TABLES:-}'
      CLICKHOUSE_TTL_HOURLY_MV_TABLES: '${CLICKHOUSE_TTL_HOURLY_MV_TABLES:-}'
      CLICKHOUSE_TTL_MINUTELY_MV_TABLES: '${CLICKHOUSE_TTL_MINUTELY_MV_TABLES:-}'
      TS_NODE_TRANSPILE_ONLY: 'true'
      LOG_LEVEL: '${LOG_LEVEL:-debug}'

  server:
    image: '${DOCKER_REGISTRY}server${DOCKER_TAG}'
    networks:
      - 'stack'
    depends_on:
      redis:
        condition: service_healthy
      clickhouse:
        condition: service_healthy
      migrations:
        condition: service_completed_successfully
      s3_provision_buckets:
        condition: service_completed_successfully
      tokens:
        condition: service_healthy
      schema:
        condition: service_healthy
      policy:
        condition: service_healthy
    ports:
      - '8082:3001'
    environment:
      NODE_ENV: production
      POSTGRES_HOST: db
      POSTGRES_PORT: 5432
      POSTGRES_DB: '${POSTGRES_DB}'
      POSTGRES_USER: '${POSTGRES_USER}'
      POSTGRES_PASSWORD: '${POSTGRES_PASSWORD}'
      CLICKHOUSE_PROTOCOL: 'http'
      CLICKHOUSE_HOST: clickhouse
      CLICKHOUSE_PORT: 8123
      CLICKHOUSE_USERNAME: '${CLICKHOUSE_USER}'
      CLICKHOUSE_PASSWORD: '${CLICKHOUSE_PASSWORD}'
      REDIS_HOST: redis
      REDIS_PORT: 6379
      REDIS_PASSWORD: '${REDIS_PASSWORD}'
      TOKENS_ENDPOINT: http://tokens:3003
      SCHEMA_ENDPOINT: http://schema:3002
      SCHEMA_POLICY_ENDPOINT: http://policy:3012
      ENCRYPTION_SECRET: '${HIVE_ENCRYPTION_SECRET}'
      WEB_APP_URL: '${HIVE_APP_BASE_URL}'
      PORT: 3001
      S3_ENDPOINT: 'http://s3:9000'
      S3_ACCESS_KEY_ID: ${MINIO_ROOT_USER}
      S3_SECRET_ACCESS_KEY: ${MINIO_ROOT_PASSWORD}
      S3_BUCKET_NAME: artifacts
      S3_AUDIT_LOG_ENDPOINT: 'http://s3:9000'
      S3_AUDIT_LOG_ACCESS_KEY_ID: ${MINIO_ROOT_USER}
      S3_AUDIT_LOG_SECRET_ACCESS_KEY: ${MINIO_ROOT_PASSWORD}
      S3_AUDIT_LOG_BUCKET_NAME: audit-logs
      CDN_AUTH_PRIVATE_KEY: ${CDN_AUTH_PRIVATE_KEY}
      CDN_API: '1'
      CDN_API_BASE_URL: 'http://localhost:8082'
      LOG_LEVEL: '${LOG_LEVEL:-debug}'
      # Auth
      AUTH_ORGANIZATION_OIDC: '1'
      AUTH_REQUIRE_EMAIL_VERIFICATION: '0'
      GRAPHQL_PUBLIC_ORIGIN: http://localhost:8082
      SUPERTOKENS_REFRESH_TOKEN_KEY: '${SUPERTOKENS_REFRESH_TOKEN_KEY}'
      SUPERTOKENS_ACCESS_TOKEN_KEY: '${SUPERTOKENS_ACCESS_TOKEN_KEY}'
      # Tracing
      OPENTELEMETRY_COLLECTOR_ENDPOINT: '${OPENTELEMETRY_COLLECTOR_ENDPOINT:-}'
      SENTRY: '${SENTRY:-0}'
      SENTRY_DSN: '${SENTRY_DSN:-}'
      PROMETHEUS_METRICS: '${PROMETHEUS_METRICS:-}'

  policy:
    image: '${DOCKER_REGISTRY}policy${DOCKER_TAG}'
    networks:
      - 'stack'
    environment:
      NODE_ENV: production
      PORT: 3012
      LOG_LEVEL: '${LOG_LEVEL:-debug}'
      OPENTELEMETRY_COLLECTOR_ENDPOINT: '${OPENTELEMETRY_COLLECTOR_ENDPOINT:-}'
      SENTRY: '${SENTRY:-0}'
      SENTRY_DSN: '${SENTRY_DSN:-}'
      PROMETHEUS_METRICS: '${PROMETHEUS_METRICS:-}'

  schema:
    image: '${DOCKER_REGISTRY}schema${DOCKER_TAG}'
    networks:
      - 'stack'
    depends_on:
      redis:
        condition: service_healthy
    environment:
      NODE_ENV: production
      PORT: 3002
      REDIS_HOST: redis
      REDIS_PORT: 6379
      REDIS_PASSWORD: '${REDIS_PASSWORD}'
      ENCRYPTION_SECRET: '${HIVE_ENCRYPTION_SECRET}'
      OPENTELEMETRY_COLLECTOR_ENDPOINT: '${OPENTELEMETRY_COLLECTOR_ENDPOINT:-}'
      SENTRY: '${SENTRY:-0}'
      SENTRY_DSN: '${SENTRY_DSN:-}'
      PROMETHEUS_METRICS: '${PROMETHEUS_METRICS:-}'
      LOG_LEVEL: '${LOG_LEVEL:-debug}'

  tokens:
    image: '${DOCKER_REGISTRY}tokens${DOCKER_TAG}'
    networks:
      - 'stack'
    depends_on:
      migrations:
        condition: service_completed_successfully
    environment:
      NODE_ENV: production
      POSTGRES_HOST: db
      POSTGRES_USER: '${POSTGRES_USER}'
      POSTGRES_PASSWORD: '${POSTGRES_PASSWORD}'
      POSTGRES_PORT: 5432
      POSTGRES_DB: '${POSTGRES_DB}'
      REDIS_HOST: redis
      REDIS_PORT: 6379
      REDIS_PASSWORD: '${REDIS_PASSWORD}'
      PORT: 3003
      LOG_LEVEL: '${LOG_LEVEL:-debug}'
      OPENTELEMETRY_COLLECTOR_ENDPOINT: '${OPENTELEMETRY_COLLECTOR_ENDPOINT:-}'
      SENTRY: '${SENTRY:-0}'
      SENTRY_DSN: '${SENTRY_DSN:-}'
      PROMETHEUS_METRICS: '${PROMETHEUS_METRICS:-}'

  workflows:
    image: '${DOCKER_REGISTRY}workflows${DOCKER_TAG}'
    networks:
      - 'stack'
    depends_on:
      db:
        condition: service_healthy
    environment:
      NODE_ENV: production
      PORT: 3014
      POSTGRES_HOST: db
      POSTGRES_PORT: 5432
      POSTGRES_DB: '${POSTGRES_DB}'
      POSTGRES_USER: '${POSTGRES_USER}'
      POSTGRES_PASSWORD: '${POSTGRES_PASSWORD}'
      EMAIL_FROM: no-reply@graphql-hive.com
      EMAIL_PROVIDER: sendmail
      LOG_LEVEL: '${LOG_LEVEL:-debug}'
      SENTRY: '${SENTRY:-0}'
      SENTRY_DSN: '${SENTRY_DSN:-}'
      PROMETHEUS_METRICS: '${PROMETHEUS_METRICS:-}'
      LOG_JSON: '1'
      SCHEMA_ENDPOINT: http://schema:3002
      REDIS_HOST: redis
      REDIS_PORT: 6379
      REDIS_PASSWORD: '${REDIS_PASSWORD}'

  usage:
    image: '${DOCKER_REGISTRY}usage${DOCKER_TAG}'
    networks:
      - 'stack'
    depends_on:
      broker:
        condition: service_healthy
      tokens:
        condition: service_healthy
    ports:
      - 8081:3006
    environment:
      NODE_ENV: production
      TOKENS_ENDPOINT: http://tokens:3003
      KAFKA_CONNECTION_MODE: 'docker'
      KAFKA_TOPIC: 'usage_reports_v2'
      KAFKA_BROKER: broker:29092
      KAFKA_BUFFER_SIZE: 350
      KAFKA_BUFFER_INTERVAL: 1000
      KAFKA_BUFFER_DYNAMIC: '1'
      POSTGRES_HOST: db
      POSTGRES_PORT: 5432
      POSTGRES_DB: '${POSTGRES_DB}'
      POSTGRES_USER: '${POSTGRES_USER}'
      POSTGRES_PASSWORD: '${POSTGRES_PASSWORD}'
      REDIS_HOST: redis
      REDIS_PORT: 6379
      REDIS_PASSWORD: '${REDIS_PASSWORD}'
      PORT: 3006
      LOG_LEVEL: '${LOG_LEVEL:-debug}'
      SENTRY: '${SENTRY:-0}'
      SENTRY_DSN: '${SENTRY_DSN:-}'
      PROMETHEUS_METRICS: '${PROMETHEUS_METRICS:-}'

  usage-ingestor:
    image: '${DOCKER_REGISTRY}usage-ingestor${DOCKER_TAG}'
    networks:
      - 'stack'
    depends_on:
      broker:
        condition: service_healthy
      clickhouse:
        condition: service_healthy
    environment:
      NODE_ENV: production
      KAFKA_CONNECTION_MODE: 'docker'
      KAFKA_BROKER: broker:29092
      KAFKA_CONCURRENCY: '1'
      KAFKA_CONSUMER_GROUP: 'usage-ingestor-v2'
      KAFKA_TOPIC: 'usage_reports_v2'
      CLICKHOUSE_PROTOCOL: 'http'
      CLICKHOUSE_HOST: clickhouse
      CLICKHOUSE_PORT: 8123
      CLICKHOUSE_USERNAME: '${CLICKHOUSE_USER}'
      CLICKHOUSE_PASSWORD: '${CLICKHOUSE_PASSWORD}'
      PORT: 3007
      LOG_LEVEL: '${LOG_LEVEL:-debug}'
      SENTRY: '${SENTRY:-0}'
      SENTRY_DSN: '${SENTRY_DSN:-}'
      PROMETHEUS_METRICS: '${PROMETHEUS_METRICS:-}'

  app:
    image: '${DOCKER_REGISTRY}app${DOCKER_TAG}'
    ports:
      - '8080:3000'
    networks:
      - 'stack'
    environment:
      PORT: 3000
      NODE_ENV: production
      APP_BASE_URL: '${HIVE_APP_BASE_URL}'
      GRAPHQL_PUBLIC_ENDPOINT: http://localhost:8082/graphql
      GRAPHQL_PUBLIC_SUBSCRIPTION_ENDPOINT: http://localhost:8082/graphql
      GRAPHQL_PUBLIC_ORIGIN: http://localhost:8082
      AUTH_REQUIRE_EMAIL_VERIFICATION: '0'
      AUTH_ORGANIZATION_OIDC: '1'
      LOG_LEVEL: '${LOG_LEVEL:-debug}'
      SENTRY: '${SENTRY:-0}'
      SENTRY_DSN: '${SENTRY_DSN:-}'
