version: "3.9"

configs:
  prometheus_config_v3:
    file: ./prometheus/prometheus.yml
  prometheus_rules_v6:
    file: ./prometheus/rules/vello.rules.yml
  alertmanager_config_v3:
    file: ./alertmanager/alertmanager.yml
  auto_heal_script_v13:
    file: ./autoheal/auto-heal.sh
  alert_webhook_script_v5:
    file: ./alertmanager/alert-webhook.py

volumes:
  prom_data:
  alertmanager_data:

services:
  prometheus:
    image: prom/prometheus:v2.52.0
    command:
      - "--config.file=/etc/prometheus/prometheus.yml"
      - "--storage.tsdb.path=/prometheus"
      - "--storage.tsdb.retention.time=7d"
      - "--web.enable-lifecycle"
    configs:
      - source: prometheus_config_v3
        target: /etc/prometheus/prometheus.yml
      - source: prometheus_rules_v6
        target: /etc/prometheus/rules/vello.rules.yml
    volumes:
      - prom_data:/prometheus
    ports:
      - target: 9090
        published: 9090
        protocol: tcp
        mode: host
    networks:
      - monitoring
      - vello-overlay
    deploy:
      placement:
        constraints:
          - node.role == manager

  prometheus-alertmanager:
    image: prom/alertmanager:v0.27.0
    command:
      - "--config.file=/etc/alertmanager/alertmanager.yml"
      - "--storage.path=/alertmanager"
    configs:
      - source: alertmanager_config_v3
        target: /etc/alertmanager/alertmanager.yml
    volumes:
      - alertmanager_data:/alertmanager
    networks:
      - monitoring
    ports:
      - target: 9093
        published: 9093
        protocol: tcp
        mode: host
    deploy:
      placement:
        constraints:
          - node.role == manager

  prometheus-node-exporter:
    image: quay.io/prometheus/node-exporter:v1.7.0
    deploy:
      mode: global
      placement:
        constraints:
          - node.platform.os == linux
    networks:
      - monitoring
    command:
      - "--path.procfs=/host/proc"
      - "--path.sysfs=/host/sys"
      - "--path.rootfs=/host"
    volumes:
      - /proc:/host/proc:ro
      - /sys:/host/sys:ro
      - /:/host:ro
    ports:
      - target: 9100
        published: 9100
        protocol: tcp
        mode: host

  auto-heal:
    image: alpine:3.20
    networks:
      - monitoring
      - vello-overlay
    deploy:
      placement:
        constraints:
          - node.role == manager
      restart_policy:
        condition: any
        delay: 5s
        max_attempts: 0
        window: 60s
    configs:
      - source: auto_heal_script_v13
        target: /usr/local/bin/vello-autoheal.sh
        mode: 0555
    environment:
      - AUTOHEAL_INTERVAL=20
      - AUTOHEAL_MAX_ATTEMPTS=3
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    command: ["sh", "-lc", "set -e; apk add --no-cache docker-cli python3 >/dev/null; mkdir -p /var/www; exec /usr/local/bin/vello-autoheal.sh"]

  prometheus-alert-webhook:
    image: python:3.11-alpine
    networks:
      - monitoring
    deploy:
      placement:
        constraints:
          - node.role == manager
      restart_policy:
        condition: any
        delay: 5s
        max_attempts: 0
        window: 60s
    configs:
      - source: alert_webhook_script_v5
        target: /usr/local/bin/alert-webhook.py
        mode: 0555
    environment:
      - ALERTS_ROUTE_VIA_API=true
      - ALERTS_API_URL=${API_INTERNAL_BASE_URL}
      - ALERTS_INTERNAL_ADMIN_TOKEN=${INTERNAL_ADMIN_TOKEN}
      # ALERTS_EMAIL_TO optional (resolved from API /api/admin/team/primary-email when unset)
      - ALERTS_EMAIL_TO=${ALERTS_EMAIL_TO}
      - ALERTS_EMAIL_FROM=${ALERTS_EMAIL_FROM}
    command: ["sh", "-lc", "set -e; apk add --no-cache curl >/dev/null; curl -LsSf https://astral.sh/uv/install.sh | sh >/dev/null; export PATH=\"/root/.local/bin:$PATH\"; uv pip install --system --no-cache-dir flask requests >/dev/null; exec python3 /usr/local/bin/alert-webhook.py"]

networks:
  monitoring:
    driver: overlay
    attachable: true
  vello-overlay:
    external: true
    name: vello-dev_vello-overlay
