Expose metrics behind hostname subpath

I have setup traefik v3 and have a couple of services sitting behind traefik. Everything is working fine so far. But I am having difficulty setting up metrics and exposing it behind a domain subpath.
Right now I got my own domain and the services are exposed via a single domain such as requests to mydomain.com goes to service 1 and requests to mydomain.com/app goes to service 2 (app service) and mydomain.com/api goes to service 3 (api service). Now what I would like to do is requests to mydomain.com/metrics should go to traefik metrics. Also I would like to setup basic auth for this subpath. My prometheus is located at another remote server hence the need to expose the metrics.

So far this is what I came up and can access the metrics via localhost:8080/metrics.
This is my traefik.yml

api:
  insecure: true

entryPoints:
  web:
    address: ":80"
    http:
      redirections:
        entryPoint:
          to: websecure
  websecure:
    address: ":443"
  metrics:
    address: ":8081"

metrics:
  prometheus:
    addEntryPointsLabels: true
    addRoutersLabels: true
    addServicesLabels: true
    entryPoint: metrics

log:
  level: DEBUG

providers:
  docker:
    endpoint: "unix:///var/run/docker.sock"

certificatesResolvers:
  letsEncrypt:
    acme:
      email: myemail@email.com
      storage: /tls/acme.json
      httpChallenge:
        entryPoint: web

http:
  middlewares:
    compressionHeaders:
      headers:
        customRequestHeaders:
          Accept-Encoding: "gzip"
    mycompress:
      compress: 
        defaultEncoding: gzip
        minResponseBodyBytes: 0
    

This is my compose file for traefik

services:
  traefik:
    container_name: traefik
    image: traefik:3.1
    ports:
      - "80:80"
      - "8080:8080"
      - "8081:8081"
      - "443:443"
    restart: unless-stopped
    volumes:
      - ./traefik.yml:/traefik.yml:ro
      - /var/run/docker.sock:/var/run/docker.sock
      - tls:/tls
    networks:
      - traefik
      - monitoring
    labels:
      - "traefik.http.routers.traefik-metrics.rule=(Host(`mydomain.com`) || Host(`www.mydomain.com`)) && PathPrefix(`/traefik`)"
      - "traefik.http.routers.traefik-metrics.entrypoints=websecure"
      - "traefik.http.routers.traefik-metrics.service=prometheus@internal"
      - "traefik.http.middlewares.strippathprefixmetrics.stripprefix.prefixes=/traefik"
      - "traefik.http.middlewares.metricsauth.basicauth.users=user:$$password"
      - "traefik.http.routers.traefik-metrics.middlewares=metricsauth,strippathprefixmetrics"
volumes:
  tls:
networks:
  traefik:
    name: traefik
    external: true
  monitoring:
    name: monitoring
    external: true

Check metrics manualRouting in doc.

Thanks for the response. The url that you provided only talks about a single option for metrics. However, I figured out the solution

here is the solution. i had to separate my config files into static and dynamic. i added a volume for my traefik compose file:

services:
  traefik:
    container_name: traefik
    image: traefik:3.1
    ports:
      - "80:80"
      - "8080:8080"
      - "443:443"
    restart: unless-stopped
    volumes:
      - ./traefik.yml:/traefik.yml:ro
      - ./provider:/provider       # <- this is the newly added bind mount
      - /var/run/docker.sock:/var/run/docker.sock
      - tls:/tls
    networks:
      - traefik
      - monitoring
volumes:
  tls:
networks:
  traefik:
    name: traefik
    external: true
  monitoring:
    name: monitoring
    external: true

this is my static config file. nothing fancy

api:
  debug: true
  dashboard: true
entryPoints:
  web:
    address: ":80"
    http:
      redirections:
        entryPoint:
          to: websecure
  websecure:
    address: ":443"
providers:
  docker:
    endpoint: "unix:///var/run/docker.sock"
  file:
    directory: "/provider"                 # <- added new provider for my dynamic config
    watch: true

metrics:
  prometheus:
    addEntryPointsLabels: true
    addRoutersLabels: true
    addServicesLabels: true
    manualRouting: true                # <- i had to enable this one as well

log:
  level: DEBUG

certificatesResolvers:
  letsEncrypt:
    acme:
      email: myemail@email.com
      storage: /tls/acme.json
      httpChallenge:
        entryPoint: web

and this is the main one. dynamic config file


http:
  middlewares:
    compressionHeaders:
      headers:
        customRequestHeaders:
          Accept-Encoding: "gzip"
    mycompress:
      compress: 
        defaultEncoding: gzip
        minResponseBodyBytes: 0
    treafikauth:
      basicAuth:
        users:
          - "user1:$password"
    treafikmetricsauth:
      basicAuth:
        users:
          - "user2:$password"
  routers:
    api:
      entryPoints:
        - websecure
      rule: "Host(`traefik.mydomain.com`) && (PathPrefix(`/api`) || PathPrefix(`/dashboard`))"
      service: api@internal
      tls:
        certResolver: letsEncrypt
      middlewares:
        - treafikauth
      
    metrics:
      entryPoints:
        - websecure
      rule: "Host(`traefik.mydomain.com`) && PathPrefix(`/metrics`)"
      service: prometheus@internal
      tls:
        certResolver: letsEncrypt
      middlewares:
        - treafikmetricsauth

however, this was not what i wanted originally. i wanted to serve metrics under a subpath but a subdomain seemed to take less hassle. leaving this here for anyone who wants to go down the rabbithole

This topic was automatically closed 3 days after the last reply. New replies are no longer allowed.