services:
  uptime-kuma:
    image: louislam/uptime-kuma:1
    container_name: home-monitoring-uptime-kuma
    restart: unless-stopped
    ports:
      - "3001:3001"
    environment:
      - TZ=Australia/Adelaide
    volumes:
      - uptime-kuma-data:/app/data
    mem_limit: 256m
    logging:
      driver: json-file
      options:
        max-size: "10m"
        max-file: "3"
    healthcheck:
      test: ["CMD-SHELL", "curl -sf http://localhost:3001/ > /dev/null || exit 1"]
      interval: 60s
      timeout: 10s
      retries: 3
      start_period: 30s

  prometheus:
    image: prom/prometheus:v3.10.0
    container_name: home-monitoring-prometheus
    restart: always
    ports:
      - "9090:9090"
    environment:
      - TZ=Australia/Adelaide
    volumes:
      - prometheus-data:/prometheus
      - ./config/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml:ro
      - ./config/prometheus/recording_rules.yml:/etc/prometheus/recording_rules.yml:ro
      - ./config/prometheus/alerts/:/etc/prometheus/alerts/:ro
    command:
      - "--config.file=/etc/prometheus/prometheus.yml"
      - "--storage.tsdb.path=/prometheus"
      - "--storage.tsdb.retention.time=14d"
      - "--storage.tsdb.retention.size=600MB"
      - "--web.enable-lifecycle"
    extra_hosts:
      - "host.docker.internal:host-gateway"
    mem_limit: 768m
    logging:
      driver: json-file
      options:
        max-size: "10m"
        max-file: "3"
    healthcheck:
      test: ["CMD-SHELL", "wget -qO- http://localhost:9090/-/healthy || exit 1"]
      interval: 30s
      timeout: 5s
      retries: 3
      start_period: 15s

  grafana:
    image: grafana/grafana-oss:12.4.0
    container_name: home-monitoring-grafana
    restart: unless-stopped
    depends_on:
      - prometheus
    ports:
      - "3000:3000"
    volumes:
      - grafana-data:/var/lib/grafana
      - ./config/grafana/provisioning/:/etc/grafana/provisioning/:ro
      - ./config/grafana/dashboards/:/var/lib/grafana/dashboards/:ro
    environment:
      - TZ=Australia/Adelaide
      - GF_SECURITY_ADMIN_USER=${HM_GRAFANA_ADMIN_USER:-admin}
      - GF_SECURITY_ADMIN_###_REDACTED
      - GF_SERVER_ROOT_URL=https://monitor.###_DOMAIN
      - GF_SMTP_ENABLED=true
      - GF_SMTP_HOST=###_IP:25
      - GF_SMTP_FROM_ADDRESS=claude@###_DOMAIN
      - GF_SMTP_FROM_NAME=Home Monitoring
      - GF_SMTP_SKIP_VERIFY=true
      - GF_USERS_ALLOW_SIGN_UP=false
      - GF_AUTH_ANONYMOUS_ENABLED=false
    mem_limit: 512m
    logging:
      driver: json-file
      options:
        max-size: "10m"
        max-file: "3"
    healthcheck:
      test: ["CMD-SHELL", "wget -qO- http://localhost:3000/api/health || exit 1"]
      interval: 30s
      timeout: 5s
      retries: 3
      start_period: 30s

  exporters:
    build:
      context: .
      dockerfile: Dockerfile.exporters
    container_name: home-monitoring-exporters
    restart: unless-stopped
    network_mode: host
    environment:
      - TZ=Australia/Adelaide
    volumes:
      - ${HM_SSH_KEY_PATH:-/root/.ssh/id_ed25519}:/root/.ssh/id_ed25519:ro
      - ./config/topology.yml:/app/config/topology.yml:ro
    env_file:
      - .env
    mem_limit: 256m
    logging:
      driver: json-file
      options:
        max-size: "10m"
        max-file: "3"
    healthcheck:
      test: ["CMD-SHELL", "python -c \"import urllib.request; urllib.request.urlopen('http://localhost:9100/health')\""]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 15s

  alertmanager:
    image: prom/alertmanager:v0.31.1
    container_name: home-monitoring-alertmanager
    restart: unless-stopped
    ports:
      - "9093:9093"
    environment:
      - TZ=Australia/Adelaide
    volumes:
      - alertmanager-data:/alertmanager
      - ./config/alertmanager/alertmanager.yml:/etc/alertmanager/alertmanager.yml:ro
    command:
      - "--config.file=/etc/alertmanager/alertmanager.yml"
      - "--storage.path=/alertmanager"
    extra_hosts:
      - "host.docker.internal:host-gateway"
    mem_limit: 128m
    logging:
      driver: json-file
      options:
        max-size: "10m"
        max-file: "3"
    healthcheck:
      test: ["CMD-SHELL", "wget -qO- http://localhost:9093/-/healthy || exit 1"]
      interval: 30s
      timeout: 5s
      retries: 3
      start_period: 10s

  dashboard:
    build:
      context: .
      dockerfile: Dockerfile.dashboard
    container_name: home-monitoring-dashboard
    restart: unless-stopped
    ports:
      - "8080:8080"
    environment:
      - TZ=Australia/Adelaide
    depends_on:
      - prometheus
      - alertmanager
    extra_hosts:
      - "host.docker.internal:host-gateway"
    mem_limit: 128m
    logging:
      driver: json-file
      options:
        max-size: "10m"
        max-file: "3"
    healthcheck:
      test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8080/health')"]
      interval: 30s
      timeout: 5s
      retries: 3
      start_period: 15s

  # Investigator runs as a systemd service on the host (not in Docker).
  # See investigator/systemd/investigator.service for the unit file.
  #
  # IMPORTANT: The host nftables firewall must allow Docker bridge traffic to port 8099.
  # On claude-internal-tools: nft add rule inet host_filter input iifname "br-*" tcp dport 8099 accept

volumes:
  uptime-kuma-data:
  prometheus-data:
  grafana-data:
  alertmanager-data:
