Its not clear how the pieces are interconnected. Entrypoint to router to service

From the documentation I couldn't understand what the different named entities map to.

Take this messed up example of mine:

  pit-site:
    image: mydomain/pit-site
    container_name: pit-site
    restart: unless-stopped
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.pit_site.rule=Host(`mydomain.net`)"
      - "traefik.http.routers.pit_site.entrypoints=websecure"
      - "traefik.http.routers.pit_site.tls=true"
      - "traefik.http.services.pit_site_service.loadbalancer.server.port=80" # Port inside the container
    networks:
      - my-dc-network
    logging:
      options:
        max-size: "15m"
        max-file: "4"

Does the name of the router need to match with the name of the service in Docker-compose. Does the name of the service need to match with the same router/service name?

I don't think its clearly mentioned in the Traefik docs how the Traefik entities map 1:1 to the Docker entities like container or service.

Also, its not very clear from the docs whether static certificates still need to be mapped via dynamic provider file. The docs focus on ACME / letsencrypt - whereas the static origin certificates from Cloudflare for example are not working for me. It is also possible my cert configuration is fine, but due to my domain mapping to container issues, the certs are also not getting picked up correctly.

Compiling my doubts/understanding:
Router:
Traefik Router is created simply by mentioning ...<routername>.rule in a container label in docker-compose. It seems all routers mentioned as labels under a container map to the Traefik service by the name of the same container/Docker service.

Service:
Traefik Service is automatically created to match with the Docker container/service. We need to only mention the service in a label if we need to change some property of the Traefik service.

Certificates:
It looks like static certificates do not need to be mapped via dynamic provider file. They can be mapped to the Traefik container with labels like tls.certificates[0].certFile.

Certificate mapping:
From entry point, Traefik looks at all routers which are attached, and then processes the rules, and for the matching rule, the Host() part of the rule is used to pick the appropriate certificate. Traefik knows the host names supported by the certificate by reading the certificate file metadata. There is no specific format to the certificate file name.

Still not clear:
Are entrypoint names like web and websecure predefined, or just conventions?

The names web and websecure are the default names used in documentation. They have to be defined in Traefik static config traefik.yml or command: for the entrypoints. Compare to simple Traefik example.

Static certificates loaded via tls in Traefik dynamic config will automatically be used, when you set tls=true or tls: {} globally on entrypoint or on every router. They are matched via Host().

Traefik labels on a Docker service/container will always target itself. You can't set a different target service/container.


Some experiments with the Docker labels for routers and services:

Single router and service works, even with different names:

    labels:
      - traefik.enable=true
      - traefik.http.routers.mywhoami1.rule=Host(`whoami-1.example.com`)
      - traefik.http.services.mywhoami100.loadbalancer.server.port=8080

Simple using multiple routers and services does not work, even with the same name:

    labels:
      - traefik.enable=true            // DOES NOT WORK
      - traefik.http.routers.mywhoami2.rule=Host(`whoami-2.example.com`)
      - traefik.http.services.mywhoami2.loadbalancer.server.port=8080
      - traefik.http.routers.mywhoami3.rule=Host(`whoami-3.example.com`)
      - traefik.http.services.mywhoami3.loadbalancer.server.port=8080

When there are multiple routers and services, you need to assign them to work:

    labels:
      - traefik.enable=true
      - traefik.http.routers.mywhoami4.rule=Host(`whoami-4.example.com`)
      - traefik.http.routers.mywhoami4.service=mywhoami4
      - traefik.http.services.mywhoami4.loadbalancer.server.port=8080
      - traefik.http.routers.mywhoami5.rule=Host(`whoami-5.example.com`)
      - traefik.http.routers.mywhoami5.service=mywhoami5
      - traefik.http.services.mywhoami5.loadbalancer.server.port=8080

With multiple routers and only a single service, the simplified version works, too:

    labels:
      - traefik.enable=true
      - traefik.http.routers.mywhoami6.rule=Host(`whoami-6.example.com`)
      - traefik.http.routers.mywhoami7.rule=Host(`whoami-7.example.com`)
      - traefik.http.services.mywhoami67.loadbalancer.server.port=8080

So the general rule for Traefik Docker labels is (probably):

  • When 1 service exists, it is automatically assigned to all routers
  • When multiple services exist, every router needs a service explicitly assigned
  • Names of routers and services do not matter
1 Like