Serving Traefik's internal dashboard behind Traefik itself

As you are using api.insecure the dashboard and api are exposed on 8080.

By using:

and

you are trying to create a routing for the api/dashboard.

but I recommend to not do that because this create some extra requests and can create infinite loop.

The recommended way to do that is to use api@internal and api.insecure=false.




Example 1:

api:
  dashboard: true

providers:
  docker:
    defaultRule: "Host(`{{ index .Labels \"com.docker.compose.service\" }}.localhost`)"
    exposedByDefault: false
    network: proxy
version: '3'
services:
  traefik:
    container_name: traefik
    image: traefik:v2.1.1
    labels:
      traefik.enable: true
      traefik.http.routers.traefik.service: api@internal
      traefik.http.routers.traefik.entrypoints: web
    networks:
      - proxy
    ports:
      - "80:80"
    restart: always
    volumes:
      - ./config:/etc/traefik
      - /var/run/docker.sock:/var/run/docker.sock:ro

networks:
  proxy:
    external: true

Example 2:

version: "3.7"

services:
  traefik:
    image: traefik:v2.1.1
    container_name: traefik
    command:
      - --log.level=INFO
      - --entrypoints.web.address=:80
      - --api
      - --providers.docker.exposedbydefault=false
      - --providers.docker.network=proxy
      - '--providers.docker.defaultRule=Host(`{{ index .Labels "com.docker.compose.service" }}.localhost`)'
    ports:
      - "80:80"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
    networks:
      - proxy
    labels:
      traefik.enable: true
      traefik.http.routers.traefik.service: api@internal
      traefik.http.routers.traefik.entrypoints: web

networks:
  proxy:
    external: true

Also I recommend to not use image: traefik:latest but an explicit version image: traefik:v2.1.1 (or image: traefik:v2.1)