version: '3.9'

services:
  prometheus:
    image: prom/prometheus:latest
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'
      - '--storage.tsdb.path=/prometheus'
      - '--storage.tsdb.retention.time=30d'
      - '--web.console.libraries=/etc/prometheus/console_libraries'
      - '--web.console.templates=/etc/prometheus/consoles'
      - '--web.enable-lifecycle'
      - '--web.enable-admin-api'
    volumes:
      - prometheus_data:/prometheus
      - prometheus_config:/etc/prometheus
    networks:
      - monitoring
      - traefik-public
    deploy:
      mode: replicated
      replicas: 1
      placement:
        constraints:
          - node.role == manager
      resources:
        limits:
          memory: 1G
        reservations:
          memory: 512M
      labels:
        - traefik.enable=true
        - traefik.docker.network=traefik-public
        - traefik.http.routers.prometheus.rule=Host(`prometheus.${DOMAIN:-localhost}`)
        - traefik.http.routers.prometheus.entrypoints=websecure
        - traefik.http.routers.prometheus.tls=true
        - traefik.http.routers.prometheus.tls.certresolver=letsencrypt
        - traefik.http.routers.prometheus.middlewares=prometheus-auth,security-headers
        - traefik.http.middlewares.prometheus-auth.basicauth.users=admin:$$2y$$10$$xvzBkbKKvRX.jGG6F7L.ReEMyEx.7BkqNGQO2rFt/1aBgx8jPElXW
        - traefik.http.services.prometheus.loadbalancer.server.port=9090

  grafana:
    image: grafana/grafana:latest
    environment:
      - GF_SECURITY_ADMIN_USER=admin
      - GF_SECURITY_ADMIN_PASSWORD=secure_grafana_2024
      - GF_USERS_ALLOW_SIGN_UP=false
      - GF_SECURITY_DISABLE_GRAVATAR=true
      - GF_ANALYTICS_REPORTING_ENABLED=false
      - GF_ANALYTICS_CHECK_FOR_UPDATES=false
    volumes:
      - grafana_data:/var/lib/grafana
      - grafana_config:/etc/grafana
    networks:
      - monitoring
      - traefik-public
    deploy:
      mode: replicated
      replicas: 1
      resources:
        limits:
          memory: 512M
        reservations:
          memory: 256M
      labels:
        - traefik.enable=true
        - traefik.docker.network=traefik-public
        - traefik.http.routers.grafana.rule=Host(`grafana.${DOMAIN:-localhost}`)
        - traefik.http.routers.grafana.entrypoints=websecure
        - traefik.http.routers.grafana.tls=true
        - traefik.http.routers.grafana.tls.certresolver=letsencrypt
        - traefik.http.routers.grafana.middlewares=security-headers
        - traefik.http.services.grafana.loadbalancer.server.port=3000

  alertmanager:
    image: prom/alertmanager:latest
    command:
      - '--config.file=/etc/alertmanager/alertmanager.yml'
      - '--storage.path=/alertmanager'
    volumes:
      - alertmanager_data:/alertmanager
      - alertmanager_config:/etc/alertmanager
    networks:
      - monitoring
      - traefik-public
    deploy:
      mode: replicated
      replicas: 1
      resources:
        limits:
          memory: 256M
        reservations:
          memory: 128M
      labels:
        - traefik.enable=true
        - traefik.docker.network=traefik-public
        - traefik.http.routers.alertmanager.rule=Host(`alertmanager.${DOMAIN:-localhost}`)
        - traefik.http.routers.alertmanager.entrypoints=websecure
        - traefik.http.routers.alertmanager.tls=true
        - traefik.http.routers.alertmanager.tls.certresolver=letsencrypt
        - traefik.http.routers.alertmanager.middlewares=alertmanager-auth,security-headers
        - traefik.http.middlewares.alertmanager-auth.basicauth.users=admin:$$2y$$10$$xvzBkbKKvRX.jGG6F7L.ReEMyEx.7BkqNGQO2rFt/1aBgx8jPElXW
        - traefik.http.services.alertmanager.loadbalancer.server.port=9093

  loki:
    image: grafana/loki:latest
    command: -config.file=/etc/loki/local-config.yaml
    volumes:
      - loki_data:/loki
    networks:
      - monitoring
    deploy:
      mode: replicated
      replicas: 1
      resources:
        limits:
          memory: 512M
        reservations:
          memory: 256M

  promtail:
    image: grafana/promtail:latest
    command: -config.file=/etc/promtail/config.yml
    volumes:
      - /var/log:/var/log:ro
      - /opt/traefik/logs:/traefik-logs:ro
      - promtail_config:/etc/promtail
    networks:
      - monitoring
    deploy:
      mode: global
      resources:
        limits:
          memory: 128M
        reservations:
          memory: 64M

volumes:
  prometheus_data:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: /opt/monitoring/prometheus/data
  prometheus_config:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: /opt/monitoring/prometheus/config
  grafana_data:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: /opt/monitoring/grafana/data
  grafana_config:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: /opt/monitoring/grafana/config
  alertmanager_data:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: /opt/monitoring/alertmanager/data
  alertmanager_config:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: /opt/monitoring/alertmanager/config
  loki_data:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: /opt/monitoring/loki/data
  promtail_config:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: /opt/monitoring/promtail/config

networks:
  monitoring:
    driver: overlay
    attachable: true
  traefik-public:
    external: true