version: "3.8"

# Default production stack: GB32960, JT808, Yutong MQTT, history, analytics.
# Legacy and optional services stay outside this compose file.
# Set LINGNIU_IMAGE_VERSION in Portainer Stack env, for example:
# main-0.1.0-SNAPSHOT-22468e7
# Override LINGNIU_IMAGE_REGISTRY / LINGNIU_IMAGE_NAMESPACE only when publishing to another registry.
x-common-env: &common-env
  TZ: Asia/Shanghai
  JAVA_OPTS: ${JAVA_OPTS:---sun-misc-unsafe-memory-access=allow -XX:+UseZGC -XX:MaxRAMPercentage=75}
  NACOS_CONFIG_ENABLED: ${NACOS_CONFIG_ENABLED:-true}
  NACOS_SERVER_ADDR: ${NACOS_SERVER_ADDR:-127.0.0.1:8848}
  NACOS_NAMESPACE: ${NACOS_NAMESPACE:-}
  NACOS_GROUP: ${NACOS_GROUP:-DEFAULT_GROUP}
  NACOS_CONFIG_FILE_EXTENSION: ${NACOS_CONFIG_FILE_EXTENSION:-yml}
  NACOS_REFRESH_ENABLED: ${NACOS_REFRESH_ENABLED:-true}
  NACOS_USERNAME: ${NACOS_USERNAME:-}
  NACOS_PASSWORD: ${NACOS_PASSWORD:-}
  KAFKA_BROKERS: ${KAFKA_BROKERS:-172.17.111.56:9092}

x-identity-mysql-env: &identity-mysql-env
  VEHICLE_IDENTITY_MYSQL_JDBC_URL: ${MYSQL_JDBC_URL:-}
  VEHICLE_IDENTITY_MYSQL_USERNAME: ${MYSQL_USERNAME:-}
  VEHICLE_IDENTITY_MYSQL_PASSWORD: ${MYSQL_PASSWORD:-}

x-redis-session-env: &redis-session-env
  REDIS_HOST: ${REDIS_HOST:-r-bp1u741kij7e51i481pd.redis.rds.aliyuncs.com}
  REDIS_PORT: ${REDIS_PORT:-6379}
  REDIS_DATABASE: ${REDIS_DATABASE:-50}
  REDIS_USERNAME: ${REDIS_USERNAME:-}
  REDIS_PASSWORD: ${REDIS_PASSWORD:-}

x-readiness-healthcheck: &readiness-healthcheck
  interval: 30s
  timeout: 5s
  retries: 3
  start_period: 60s

services:
  gb32960-ingest-app:
    image: ${LINGNIU_IMAGE_REGISTRY:-crpi-85r4m0ackrm3qpje.cn-shanghai.personal.cr.aliyuncs.com}/${LINGNIU_IMAGE_NAMESPACE:-oneos}/gb32960-ingest-app:${LINGNIU_IMAGE_VERSION:?set LINGNIU_IMAGE_VERSION}
    container_name: gb32960-ingest-app
    restart: unless-stopped
    mem_limit: ${GB32960_MEM_LIMIT:-768m}
    environment:
      <<:
        - *common-env
        - *identity-mysql-env
        - *redis-session-env
      HTTP_PORT: 20100
      GB32960_PORT: 32960
      KAFKA_NODE_ID: ${KAFKA_NODE_ID:-gb32960-ingest-portainer}
      KAFKA_TOPIC_GB32960_EVENT: ${KAFKA_TOPIC_GB32960_EVENT:-vehicle.event.gb32960.v1}
      KAFKA_TOPIC_GB32960_RAW: ${KAFKA_TOPIC_GB32960_RAW:-vehicle.raw.gb32960.v1}
      KAFKA_TOPIC_GB32960_DLQ: ${KAFKA_TOPIC_GB32960_DLQ:-vehicle.dlq.gb32960.v1}
      GB32960_AUTH_ENABLED: ${GB32960_AUTH_ENABLED:-false}
      GB32960_PLATFORM_USER_HYUNDAI: ${GB32960_PLATFORM_USER_HYUNDAI:-Hyundai}
      GB32960_PLATFORM_PWD_HYUNDAI: ${GB32960_PLATFORM_PWD_HYUNDAI:-}
      GB32960_PLATFORM_IP_HYUNDAI: ${GB32960_PLATFORM_IP_HYUNDAI:-}
      GB32960_PLATFORM_USER_YUEJIN: ${GB32960_PLATFORM_USER_YUEJIN:-YueJin}
      GB32960_PLATFORM_PWD_YUEJIN: ${GB32960_PLATFORM_PWD_YUEJIN:-}
      GB32960_PLATFORM_IP_YUEJIN: ${GB32960_PLATFORM_IP_YUEJIN:-}
      GB32960_TLS_ENABLED: ${GB32960_TLS_ENABLED:-false}
      SINK_ARCHIVE_PATH: ${GB32960_ARCHIVE_PATH:-/data/archive}
    ports:
      - "${GB32960_HTTP_PORT:-20100}:20100"
      - "${GB32960_TCP_PORT:-32960}:32960"
    volumes:
      - gb32960-ingest-data:/data
    networks:
      - vehicle-ingest
    healthcheck:
      <<: *readiness-healthcheck
      test: ["CMD-SHELL", "curl -fsS http://127.0.0.1:20100/actuator/health/readiness >/dev/null"]

  jt808-ingest-app:
    image: ${LINGNIU_IMAGE_REGISTRY:-crpi-85r4m0ackrm3qpje.cn-shanghai.personal.cr.aliyuncs.com}/${LINGNIU_IMAGE_NAMESPACE:-oneos}/jt808-ingest-app:${LINGNIU_IMAGE_VERSION:?set LINGNIU_IMAGE_VERSION}
    container_name: jt808-ingest-app
    restart: unless-stopped
    mem_limit: ${JT808_MEM_LIMIT:-768m}
    environment:
      <<:
        - *common-env
        - *identity-mysql-env
        - *redis-session-env
      HTTP_PORT: 20400
      JT808_PORT: 808
      KAFKA_NODE_ID: ${KAFKA_NODE_ID_JT808:-jt808-ingest-portainer}
      KAFKA_TOPIC_JT808_EVENT: ${KAFKA_TOPIC_JT808_EVENT:-vehicle.event.jt808.v1}
      KAFKA_TOPIC_JT808_RAW: ${KAFKA_TOPIC_JT808_RAW:-vehicle.raw.jt808.v1}
      KAFKA_TOPIC_JT808_DLQ: ${KAFKA_TOPIC_JT808_DLQ:-vehicle.dlq.jt808.v1}
      SINK_ARCHIVE_PATH: ${JT808_ARCHIVE_PATH:-/data/archive}
    ports:
      - "${JT808_HTTP_PORT:-20400}:20400"
      - "${JT808_TCP_PORT:-808}:808"
    volumes:
      - jt808-ingest-data:/data
    networks:
      - vehicle-ingest
    healthcheck:
      <<: *readiness-healthcheck
      test: ["CMD-SHELL", "curl -fsS http://127.0.0.1:20400/actuator/health/readiness >/dev/null"]

  yutong-mqtt-app:
    image: ${LINGNIU_IMAGE_REGISTRY:-crpi-85r4m0ackrm3qpje.cn-shanghai.personal.cr.aliyuncs.com}/${LINGNIU_IMAGE_NAMESPACE:-oneos}/yutong-mqtt-app:${LINGNIU_IMAGE_VERSION:?set LINGNIU_IMAGE_VERSION}
    container_name: yutong-mqtt-app
    restart: unless-stopped
    mem_limit: ${YUTONG_MQTT_MEM_LIMIT:-512m}
    environment:
      <<:
        - *common-env
        - *identity-mysql-env
      HTTP_PORT: 20500
      YUTONG_MQTT_ENABLED: ${YUTONG_MQTT_ENABLED:-false}
      YUTONG_MQTT_AUTO_STARTUP: ${YUTONG_MQTT_AUTO_STARTUP:-true}
      KAFKA_NODE_ID: ${KAFKA_NODE_ID_MQTT:-yutong-mqtt-portainer}
      KAFKA_TOPIC_YUTONG_MQTT_EVENT: ${KAFKA_TOPIC_YUTONG_MQTT_EVENT:-vehicle.event.mqtt-yutong.v1}
      KAFKA_TOPIC_YUTONG_MQTT_RAW: ${KAFKA_TOPIC_YUTONG_MQTT_RAW:-vehicle.raw.mqtt-yutong.v1}
      KAFKA_TOPIC_YUTONG_MQTT_DLQ: ${KAFKA_TOPIC_YUTONG_MQTT_DLQ:-vehicle.dlq.mqtt-yutong.v1}
      YUTONG_MQTT_ENDPOINT_NAME: ${YUTONG_MQTT_ENDPOINT_NAME:-yutong}
      YUTONG_MQTT_URI: ${YUTONG_MQTT_URI:-}
      YUTONG_MQTT_TOPIC: "${YUTONG_MQTT_TOPIC:-#}"
      YUTONG_MQTT_QOS: ${YUTONG_MQTT_QOS:-1}
      YUTONG_MQTT_CLIENT_ID: ${YUTONG_MQTT_CLIENT_ID:-lingniu-yutong-mqtt}
      YUTONG_MQTT_USERNAME: ${YUTONG_MQTT_USERNAME:-}
      YUTONG_MQTT_PASSWORD: ${YUTONG_MQTT_PASSWORD:-}
      YUTONG_MQTT_CLEAN_SESSION: ${YUTONG_MQTT_CLEAN_SESSION:-false}
      YUTONG_MQTT_KEEP_ALIVE_SECONDS: ${YUTONG_MQTT_KEEP_ALIVE_SECONDS:-20}
      YUTONG_MQTT_CONNECTION_TIMEOUT_SECONDS: ${YUTONG_MQTT_CONNECTION_TIMEOUT_SECONDS:-10}
      YUTONG_MQTT_TLS_CA_PEM: ${YUTONG_MQTT_TLS_CA_PEM:-}
      YUTONG_MQTT_TLS_CLIENT_PEM: ${YUTONG_MQTT_TLS_CLIENT_PEM:-}
      YUTONG_MQTT_TLS_CLIENT_KEY: ${YUTONG_MQTT_TLS_CLIENT_KEY:-}
      YUTONG_MQTT_TLS_HOSTNAME_VERIFICATION_ENABLED: ${YUTONG_MQTT_TLS_HOSTNAME_VERIFICATION_ENABLED:-true}
      SINK_ARCHIVE_PATH: ${YUTONG_MQTT_ARCHIVE_PATH:-/data/archive}
    ports:
      - "${YUTONG_MQTT_HTTP_PORT:-20500}:20500"
    volumes:
      - yutong-mqtt-data:/data
    networks:
      - vehicle-ingest
    healthcheck:
      <<: *readiness-healthcheck
      test: ["CMD-SHELL", "curl -fsS http://127.0.0.1:20500/actuator/health/readiness >/dev/null"]

  vehicle-history-app:
    image: ${LINGNIU_IMAGE_REGISTRY:-crpi-85r4m0ackrm3qpje.cn-shanghai.personal.cr.aliyuncs.com}/${LINGNIU_IMAGE_NAMESPACE:-oneos}/vehicle-history-app:${LINGNIU_IMAGE_VERSION:?set LINGNIU_IMAGE_VERSION}
    container_name: vehicle-history-app
    restart: unless-stopped
    mem_limit: ${VEHICLE_HISTORY_MEM_LIMIT:-1536m}
    depends_on:
      - gb32960-ingest-app
      - jt808-ingest-app
      - yutong-mqtt-app
    environment:
      <<: *common-env
      HTTP_PORT: 20200
      KAFKA_CONSUMER_ENABLED: ${KAFKA_CONSUMER_ENABLED_HISTORY:-true}
      KAFKA_CONSUMER_CLIENT_ID_PREFIX: ${KAFKA_CONSUMER_CLIENT_ID_PREFIX_HISTORY:-vehicle-history}
      KAFKA_CONSUMER_MAX_POLL_RECORDS: ${KAFKA_CONSUMER_MAX_POLL_RECORDS_HISTORY:-2000}
      KAFKA_CONSUMER_MAX_POLL_INTERVAL_MILLIS: ${KAFKA_CONSUMER_MAX_POLL_INTERVAL_MILLIS_HISTORY:-1800000}
      KAFKA_TOPIC_GB32960_EVENT: ${KAFKA_TOPIC_GB32960_EVENT:-vehicle.event.gb32960.v1}
      KAFKA_TOPIC_GB32960_RAW: ${KAFKA_TOPIC_GB32960_RAW:-vehicle.raw.gb32960.v1}
      KAFKA_TOPIC_JT808_EVENT: ${KAFKA_TOPIC_JT808_EVENT:-vehicle.event.jt808.v1}
      KAFKA_TOPIC_JT808_RAW: ${KAFKA_TOPIC_JT808_RAW:-vehicle.raw.jt808.v1}
      KAFKA_TOPIC_YUTONG_MQTT_EVENT: ${KAFKA_TOPIC_YUTONG_MQTT_EVENT:-vehicle.event.mqtt-yutong.v1}
      KAFKA_TOPIC_YUTONG_MQTT_RAW: ${KAFKA_TOPIC_YUTONG_MQTT_RAW:-vehicle.raw.mqtt-yutong.v1}
      KAFKA_GROUP_HISTORY: ${KAFKA_GROUP_HISTORY:-vehicle-history}
      TDENGINE_HISTORY_ENABLED: ${TDENGINE_HISTORY_ENABLED:-true}
      TDENGINE_JDBC_URL: ${TDENGINE_JDBC_URL:-jdbc:TAOS-WS://172.17.111.57:6041/vehicle_ts}
      TDENGINE_HISTORY_DATABASE: ${TDENGINE_HISTORY_DATABASE:-vehicle_ts}
      TDENGINE_USERNAME: ${TDENGINE_USERNAME:-root}
      TDENGINE_PASSWORD: ${TDENGINE_PASSWORD:-taosdata}
      TDENGINE_CONNECTION_TIMEOUT_MILLIS: ${TDENGINE_CONNECTION_TIMEOUT_MILLIS:-30000}
      TDENGINE_MIN_IDLE: ${TDENGINE_MIN_IDLE:-1}
      TDENGINE_MAX_POOL_SIZE: ${TDENGINE_MAX_POOL_SIZE:-32}
    ports:
      - "${VEHICLE_HISTORY_HTTP_PORT:-20200}:20200"
    networks:
      - vehicle-ingest
    healthcheck:
      <<: *readiness-healthcheck
      test: ["CMD-SHELL", "curl -fsS http://127.0.0.1:20200/actuator/health/readiness >/dev/null"]

  vehicle-analytics-app:
    image: ${LINGNIU_IMAGE_REGISTRY:-crpi-85r4m0ackrm3qpje.cn-shanghai.personal.cr.aliyuncs.com}/${LINGNIU_IMAGE_NAMESPACE:-oneos}/vehicle-analytics-app:${LINGNIU_IMAGE_VERSION:?set LINGNIU_IMAGE_VERSION}
    container_name: vehicle-analytics-app
    restart: unless-stopped
    mem_limit: ${VEHICLE_ANALYTICS_MEM_LIMIT:-1024m}
    depends_on:
      - jt808-ingest-app
    environment:
      <<: *common-env
      HTTP_PORT: 20300
      KAFKA_CONSUMER_ENABLED: ${KAFKA_CONSUMER_ENABLED_ANALYTICS:-true}
      KAFKA_CONSUMER_CLIENT_ID_PREFIX: ${KAFKA_CONSUMER_CLIENT_ID_PREFIX_ANALYTICS:-vehicle-analytics}
      KAFKA_CONSUMER_MAX_POLL_INTERVAL_MILLIS: ${KAFKA_CONSUMER_MAX_POLL_INTERVAL_MILLIS_ANALYTICS:-900000}
      KAFKA_TOPIC_JT808_EVENT: ${KAFKA_TOPIC_JT808_EVENT:-vehicle.event.jt808.v1}
      KAFKA_TOPIC_JT808_DLQ: ${KAFKA_TOPIC_JT808_DLQ:-vehicle.dlq.jt808.v1}
      KAFKA_GROUP_STAT: ${KAFKA_GROUP_STAT:-vehicle-stat}
      VEHICLE_STAT_ENABLED: ${VEHICLE_STAT_ENABLED:-true}
      VEHICLE_STAT_ZONE_ID: ${VEHICLE_STAT_ZONE_ID:-Asia/Shanghai}
      VEHICLE_STAT_JT808_MILEAGE_ENABLED: ${VEHICLE_STAT_JT808_MILEAGE_ENABLED:-true}
      MYSQL_JDBC_URL: ${MYSQL_JDBC_URL:-}
      MYSQL_USERNAME: ${MYSQL_USERNAME:-}
      MYSQL_PASSWORD: ${MYSQL_PASSWORD:-}
    ports:
      - "${VEHICLE_ANALYTICS_HTTP_PORT:-20300}:20300"
    networks:
      - vehicle-ingest
    healthcheck:
      <<: *readiness-healthcheck
      test: ["CMD-SHELL", "curl -fsS http://127.0.0.1:20300/actuator/health/readiness >/dev/null"]

networks:
  vehicle-ingest:
    name: vehicle-ingest

volumes:
  gb32960-ingest-data:
  jt808-ingest-data:
  yutong-mqtt-data:
