version: '3.8'
name: fzx-aliyun-monitoring

networks:
  fzx-devops-net:
    external: true
    name: fzx-devops-net

volumes:
  fzx-aliyun-prometheus-data:
    name: fzx-aliyun-prometheus-data
    driver: local
  fzx-aliyun-grafana-data:
    name: fzx-aliyun-grafana-data
    driver: local
  fzx-aliyun-loki-data:
    name: fzx-aliyun-loki-data
    driver: local

services:
  prometheus:
    image: docker.m.daocloud.io/prom/prometheus:v2.54.1
    container_name: fzx-aliyun-prometheus
    restart: always
    networks:
      fzx-devops-net:
        aliases:
          - prometheus
    volumes:
      - fzx-aliyun-prometheus-data:/prometheus
      - /opt/fzx/config/prometheus/prometheus.aliyun.yml:/etc/prometheus/prometheus.yml:ro
      - /opt/fzx/config/prometheus/rules:/etc/prometheus/rules:ro
    ports:
      - "0.0.0.0:9090:9090"
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'
      - '--storage.tsdb.path=/prometheus'
      - '--web.console.libraries=/etc/prometheus/console_libraries'
      - '--web.console.templates=/etc/prometheus/consoles'
      - '--web.enable-lifecycle'
    healthcheck:
      test: [ "CMD", "wget", "--spider", "http://localhost:9090/-/healthy" ]
      interval: 30s
      timeout: 10s
      retries: 3
    deploy:
      resources:
        limits:
          cpus: "0.5"
          memory: "512M"
        reservations:
          cpus: "0.25"
          memory: "256M"
    logging:
      driver: "json-file"
      options:
        max-size: "100m"
        max-file: "10"
    depends_on:
      alertmanager:
        condition: service_healthy

  alertmanager:
    image: docker.m.daocloud.io/prom/alertmanager:v0.27.0
    container_name: fzx-aliyun-alertmanager
    restart: always
    networks:
      fzx-devops-net:
        aliases:
          - alertmanager
    volumes:
      - /opt/fzx/config/prometheus/alertmanager.yml:/etc/alertmanager/alertmanager.yml:ro
    ports:
      - "0.0.0.0:9093:9093"
    command:
      - '--config.file=/etc/alertmanager/alertmanager.yml'
      - '--storage.path=/alertmanager'
    healthcheck:
      test: [ "CMD", "wget", "--spider", "http://localhost:9093/-/healthy" ]
      interval: 30s
      timeout: 10s
      retries: 3
    deploy:
      resources:
        limits:
          cpus: "0.2"
          memory: "128M"
        reservations:
          cpus: "0.1"
          memory: "64M"
    logging:
      driver: "json-file"
      options:
        max-size: "100m"
        max-file: "10"

  grafana:
    image: docker.m.daocloud.io/grafana/grafana:11.2.0
    container_name: fzx-aliyun-grafana
    restart: always
    networks:
      fzx-devops-net:
        aliases:
          - grafana
    volumes:
      - fzx-aliyun-grafana-data:/var/lib/grafana
      - /opt/fzx/config/grafana/datasources:/etc/grafana/provisioning/datasources:ro
      - /opt/fzx/config/grafana/dashboards:/etc/grafana/provisioning/dashboards:ro
    ports:
      - "0.0.0.0:3000:3000"
    environment:
      GF_SECURITY_ADMIN_USER: ${GRAFANA_USER:-admin}
      GF_SECURITY_ADMIN_PASSWORD: ${GRAFANA_PASSWORD:-fzx@2024!grafana}
      GF_INSTALL_PLUGINS: 
      GF_DASHBOARDS_DEFAULT_HOME_DASHBOARD_PATH: /etc/grafana/provisioning/dashboards/spring-boot-dashboard.json
    healthcheck:
      test: [ "CMD", "wget", "-qO-", "http://localhost:3000/api/health" ]
      interval: 30s
      timeout: 10s
      retries: 3
    deploy:
      resources:
        limits:
          cpus: "0.3"
          memory: "384M"
        reservations:
          cpus: "0.15"
          memory: "192M"
    logging:
      driver: "json-file"
      options:
        max-size: "100m"
        max-file: "10"

  loki:
    image: docker.m.daocloud.io/grafana/loki:2.9.0
    container_name: fzx-aliyun-loki
    restart: always
    networks:
      fzx-devops-net:
        aliases:
          - loki
    volumes:
      - fzx-aliyun-loki-data:/loki
      - /opt/fzx/config/loki/loki.yml:/etc/loki/loki.yml:ro
    ports:
      - "0.0.0.0:3100:3100"
    command:
      - '--config.file=/etc/loki/loki.yml'
    # 注: Loki 使用 scratch 基础镜像，无法执行容器内健康检查
    # 通过 Prometheus blackbox_exporter 进行外部健康监控
    deploy:
      resources:
        limits:
          cpus: "0.5"
          memory: "1G"
        reservations:
          cpus: "0.25"
          memory: "512M"
    logging:
      driver: "json-file"
      options:
        max-size: "100m"
        max-file: "10"

  promtail:
    image: docker.m.daocloud.io/grafana/promtail:2.9.0
    container_name: fzx-aliyun-promtail
    restart: always
    networks:
      fzx-devops-net:
        aliases:
          - promtail
    volumes:
      - /opt/fzx/config/loki/promtail.yml:/etc/promtail/promtail.yml:ro
      - /var/log/fzx:/var/log/fzx
      - /run/podman/podman.sock:/run/podman/podman.sock
    command:
      - '--config.file=/etc/promtail/promtail.yml'
    healthcheck:
      test: ["CMD-SHELL", "bash -c ':> /dev/tcp/127.0.0.1/9080'"]
      interval: 30s
      timeout: 10s
      retries: 3
    deploy:
      resources:
        limits:
          cpus: "0.3"
          memory: "256M"
        reservations:
          cpus: "0.15"
          memory: "128M"
    logging:
      driver: "json-file"
      options:
        max-size: "100m"
        max-file: "10"
    depends_on:
      loki:
        condition: service_healthy

  # Nginx 指标采集器 - Prometheus Exporter for Nginx
  # 使用官方 nginx-prometheus-exporter 镜像
  nginx-exporter:
    image: docker.1ms.run/nginx/nginx-prometheus-exporter:1.3.0
    container_name: fzx-aliyun-nginx-exporter
    restart: always
    networks:
      fzx-devops-net:
        aliases:
          - nginx-exporter
    command:
      - '--nginx.scrape-uri=http://fzx-aliyun-nginx:80/nginx_status'
    ports:
      - "0.0.0.0:9113:9113"
    # 注: scratch 精简镜像不支持容器内健康检查，通过 Podman 自动重启保障可用性
    deploy:
      resources:
        limits:
          cpus: "0.1"
          memory: "64M"
        reservations:
          cpus: "0.05"
          memory: "32M"
    logging:
      driver: "json-file"
      options:
        max-size: "50m"
        max-file: "5"

  # 钉钉告警转发器 - 使用官方 prometheus-webhook-dingtalk
  # 接收 AlertManager 告警并转发至钉钉
  dingtalk-webhook:
    image: docker.1ms.run/timonwong/prometheus-webhook-dingtalk:v2.1.0
    container_name: fzx-dingtalk-webhook
    restart: always
    networks:
      fzx-devops-net:
        aliases:
          - dingtalk-webhook
    ports:
      - "0.0.0.0:8060:8060"
    volumes:
      - /opt/fzx/config/prometheus/webhook-dingtalk.yml:/etc/prometheus-webhook-dingtalk/config.yml:ro
    command:
      - '--config.file=/etc/prometheus-webhook-dingtalk/config.yml'
      - '--web.listen-address=:8060'
      - '--web.enable-ui'
    # 注: prometheus-webhook-dingtalk 使用 scratch 基础镜像，无法执行容器内健康检查
    # 通过 Prometheus blackbox_exporter 进行外部健康监控
    deploy:
      resources:
        limits:
          cpus: "0.1"
          memory: "64M"
        reservations:
          cpus: "0.05"
          memory: "32M"
    logging:
      driver: "json-file"
      options:
        max-size: "50m"
        max-file: "5"


