Traefik ignoring my http router in traefik.toml

I am trying to setup a 2-service traefik server. For this, I've made a docker file pulling traefik v2.0.2, and using a specific .toml file. I can assure the toml file is indeed read by traefik, as changing the log level or removing [api] has the expected effect.

However, my routes are nowhere to be seen in the dashboard : the only ones I see are some that traefik auto-generates when one of my container has traefik enabled.
In the logs here, that would equate to folio-traefik.

What could the problem be here ? Thanks !

docker-compose.yml

version: "3.3"

networks:
  default:
    external: false
  gitea:
    external: false

services:

  traefik:
    image: "traefik:v2.0.2"
    container_name: "traefik"
    networks:
      - default
    ports:
      - "80:80"
      - "443:443"
      - "8080:8080"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
      - "/home/me/traefik/letsencrypt:/letsencrypt"
      - "/home/me/traefik/traefik.toml:/etc/traefik/traefik.toml"

    #Other containers, such as my portfolio and personal gitea, both on the default network together with traefik

traefik.toml

File Edit Options Buffers Tools Help
[entryPoints]
  [entryPoints.web]
    address = ":80"

  [entryPoints.websecure]
    address = ":443"

[http.routers]

  [http.routers.test-router]
    rule = "Path(`/foo`)"
    service = "service-foo"

  [http.routers.folio-router]
    rule = "Host(`mydomain.com`)"
    service = "folio-traefik"
    entrypoints = ["websecure"]
    [http.routers.folio-router.tls]
      certResolver = "myhttpchallenge"

  [http.routers.gitea-router]
    rule = "Host(`git.mydomain.com`)"
    service = "gitea-traefik"
    entrypoints = ["websecure"]
    [http.routers.gitea-router.tls]
      certResolver = "myhttpchallenge"


[providers.docker]
  exposedByDefault = false
  network = "traefik_traefik"

[certificatesResolvers.myhttpchallenge.acme]
  email = "myemail@gmail.com"
  storage = "/letsencrypt/acme.json"
  [certificatesResolvers.myhttpchallenge.acme.httpChallenge]
    entryPoint = "web"


[api]
  insecure = true

[accessLog]

[log]
  level = "DEBUG"

traefik logs, with only my portfolio container enabled :

me@vultr:[~/traefik]: docker container logs traefik
time="2019-10-20T16:08:55Z" level=info msg="Configuration loaded from file: /etc/traefik/traefik.toml"
time="2019-10-20T16:08:55Z" level=info msg="Traefik version 2.0.2 built on 2019-10-09T19:26:05Z"
time="2019-10-20T16:08:55Z" level=debug msg="Static configuration loaded {\"global\":{\"checkNewVersion\":true},\"serversTransport\":{\"maxIdleConnsPerHost\":200},\"entryPoints\":{\"traefik\":{\"address\":\":8080\",\"transport\":{\"lifeCycle\":{\"graceTimeOut\":10000000000},\"respondingTimeouts\":{\"idleTimeout\":180000000000}},\"forwardedHeaders\":{}},\"web\":{\"address\":\":80\",\"transport\":{\"lifeCycle\":{\"graceTimeOut\":10000000000},\"respondingTimeouts\":{\"idleTimeout\":180000000000}},\"forwardedHeaders\":{}},\"websecure\":{\"address\":\":443\",\"transport\":{\"lifeCycle\":{\"graceTimeOut\":10000000000},\"respondingTimeouts\":{\"idleTimeout\":180000000000}},\"forwardedHeaders\":{}}},\"providers\":{\"providersThrottleDuration\":2000000000,\"docker\":{\"watch\":true,\"endpoint\":\"unix:///var/run/docker.sock\",\"defaultRule\":\"Host(`{{ normalize .Name }}`)\",\"network\":\"traefik_default\",\"swarmModeRefreshSeconds\":15000000000}},\"api\":{\"insecure\":true,\"dashboard\":true},\"log\":{\"level\":\"DEBUG\",\"format\":\"common\"},\"accessLog\":{\"format\":\"common\",\"filters\":{},\"fields\":{\"defaultMode\":\"keep\",\"headers\":{\"defaultMode\":\"drop\"}}},\"certificatesResolvers\":{\"myhttpchallenge\":{\"acme\":{\"email\":\"myemail@gmail.com\",\"caServer\":\"https://acme-v02.api.letsencrypt.org/directory\",\"storage\":\"/letsencrypt/acme.json\",\"keyType\":\"RSA4096\",\"httpChallenge\":{\"entryPoint\":\"web\"}}}}}"
time="2019-10-20T16:08:55Z" level=info msg="\nStats collection is disabled.\nHelp us improve Traefik by turning this feature on :)\nMore details on: https://docs.traefik.io/v2.0/contributing/data-collection/\n"
time="2019-10-20T16:08:55Z" level=debug msg="No default certificate, generating one"
time="2019-10-20T16:08:56Z" level=info msg="Starting provider aggregator.ProviderAggregator {}"
time="2019-10-20T16:08:56Z" level=debug msg="Start TCP Server" entryPointName=web
time="2019-10-20T16:08:56Z" level=debug msg="Start TCP Server" entryPointName=websecure
time="2019-10-20T16:08:56Z" level=debug msg="Start TCP Server" entryPointName=traefik
time="2019-10-20T16:08:56Z" level=info msg="Starting provider *acme.Provider {\"email\":\"myemail@gmail.com\",\"caServer\":\"https://acme-v02.api.letsencrypt.org/directory\",\"storage\":\"/letsencrypt/acme.json\",\"keyType\":\"RSA4096\",\"httpChallenge\":{\"entryPoint\":\"web\"},\"ResolverName\":\"myhttpchallenge\",\"store\":{},\"ChallengeStore\":{}}"
time="2019-10-20T16:08:56Z" level=info msg="Testing certificate renew..." providerName=myhttpchallenge.acme
time="2019-10-20T16:08:56Z" level=info msg="Starting provider *docker.Provider {\"watch\":true,\"endpoint\":\"unix:///var/run/docker.sock\",\"defaultRule\":\"Host(`{{ normalize .Name }}`)\",\"network\":\"traefik_default\",\"swarmModeRefreshSeconds\":15000000000}"
time="2019-10-20T16:08:56Z" level=debug msg="Configuration received from provider myhttpchallenge.acme: {\"http\":{},\"tls\":{}}" providerName=myhttpchallenge.acme
time="2019-10-20T16:08:56Z" level=debug msg="Adding certificate for domain(s) mydomain.com"
time="2019-10-20T16:08:56Z" level=debug msg="Adding certificate for domain(s) git.mydomain.com"
time="2019-10-20T16:08:56Z" level=debug msg="No default certificate, generating one"
time="2019-10-20T16:08:56Z" level=debug msg="Provider connection established with docker 18.09.1 (API 1.39)" providerName=docker
time="2019-10-20T16:08:56Z" level=debug msg="Filtering disabled container" providerName=docker container=traefik-traefik-e9c452c6f75c1c8c226aa9de319af8d72a92afb71b3f3d859ebfe47451ead09e
time="2019-10-20T16:08:56Z" level=debug msg="Configuration received from provider docker: {\"http\":{\"routers\":{\"folio-traefik\":{\"service\":\"folio-traefik\",\"rule\":\"Host(`folio-traefik`)\"}},\"services\":{\"folio-traefik\":{\"loadBalancer\":{\"servers\":[{\"url\":\"http://172.31.0.3:80\"}],\"passHostHeader\":true}}}},\"tcp\":{}}" providerName=docker
time="2019-10-20T16:08:56Z" level=debug msg="Adding certificate for domain(s) mydomain.com"
time="2019-10-20T16:08:56Z" level=debug msg="Adding certificate for domain(s) git.mydomain.com"
time="2019-10-20T16:08:56Z" level=debug msg="No default certificate, generating one"
time="2019-10-20T16:08:57Z" level=debug msg="No entryPoint defined for this router, using the default one(s) instead: [web websecure traefik]" routerName=folio-traefik@docker
time="2019-10-20T16:08:57Z" level=debug msg="Creating middleware" middlewareName=pipelining entryPointName=web routerName=folio-traefik@docker serviceName=folio-traefik middlewareType=Pipelining
time="2019-10-20T16:08:57Z" level=debug msg="Creating load-balancer" entryPointName=web routerName=folio-traefik@docker serviceName=folio-traefik
time="2019-10-20T16:08:57Z" level=debug msg="Creating server 0 http://172.31.0.3:80" serverName=0 serviceName=folio-traefik entryPointName=web routerName=folio-traefik@docker
time="2019-10-20T16:08:57Z" level=debug msg="Added outgoing tracing middleware folio-traefik" middlewareType=TracingForwarder entryPointName=web routerName=folio-traefik@docker middlewareName=tracing
time="2019-10-20T16:08:57Z" level=debug msg="Creating middleware" entryPointName=web middlewareName=traefik-internal-recovery middlewareType=Recovery
time="2019-10-20T16:08:57Z" level=debug msg="Creating middleware" middlewareName=traefik-internal-recovery middlewareType=Recovery entryPointName=websecure
time="2019-10-20T16:08:57Z" level=debug msg="Creating middleware" entryPointName=traefik middlewareName=traefik-internal-recovery middlewareType=Recovery

Hello,

In the v2 the static configuration and the dynamic configuration cannot be mixed by default: you have to create 2 files.

Like with v1, the file provider must be enable to read dynamic configuration from a file.

traefik.toml:

# static configuration
[entryPoints]
  [entryPoints.web]
    address = ":80"

  [entryPoints.websecure]
    address = ":443"

[providers.docker]
  exposedByDefault = false
  network = "traefik_traefik"

[providers.file]
  directory = "/etc/traefik/config/"

[certificatesResolvers.myhttpchallenge.acme]
  email = "myemail@gmail.com"
  storage = "/letsencrypt/acme.json"
  [certificatesResolvers.myhttpchallenge.acme.httpChallenge]
    entryPoint = "web"

[api]
  insecure = true

[accessLog]

[log]
  level = "DEBUG"

/home/me/traefik/config/dyn.toml

[http.routers]
  [http.routers.test]
    rule = "Path(`/foo`)"
    service = "test"

[http.services]
  [http.services.test]
    [[http.services.test.loadBalancer.servers]]
      url = "https://google.com"

And also I recommend to use labels instead of file to set routes on containers.

version: "3.3"

networks:
  default:
    external: false
  gitea:
    external: false

services:

  traefik:
    image: "traefik:v2.0.2"
    container_name: "traefik"
    networks:
      - default
    ports:
      - "80:80"
      - "443:443"
      - "8080:8080"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
      - "/home/me/traefik/letsencrypt:/letsencrypt"
      - "/home/me/traefik/traefik.toml:/etc/traefik/traefik.toml"
      - "/home/me/traefik/config:/etc/traefik/config/"
  
  portfolio:
    image: "xxx"
    labels:
      - traefik.http.routers.folio.rule=Host(`mydomain.com`)
      - traefik.http.routers.folio.entrypoints=websecure
      - traefik.http.routers.folio.tls.certResolver=myhttpchallenge
  
  gitea:
    image: "xxx"
    labels:
      - traefik.http.routers.gitea.rule=Host(`git.mydomain.com`)
      - traefik.http.routers.gitea.entrypoints=websecure
      - traefik.http.routers.gitea.tls.certResolver=myhttpchallenge
1 Like

Thanks!
Out of curiosity, why would you recommend using the labels instead of a config file for the dynamic config ?
From reading the docs, I thought the labels were more of a temporary solution when trying out settings for a new config.

The file provider was made for old system (VM or server on real machine), for the routing it's the worst solution.

Labels are not a temporary solution, it's the best solution to have a dynamic configuration when using containers. Because with labels, each container manages its own configuration, that allow to refresh the configuration automatically.

The goal of Traefik is to manage dynamically the routing:

  • when a new container appears, Traefik creates automatically the routing
  • when a container disappears, Traefik removes automatically the routing
3 Likes

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