6

Is there any way to set traefik.http.services name in docker-compose labels?

Lets say i have simple docker-compose.yml:

version: '3.4'

services:
  traefik:
    image: "traefik:v2.4.2"
    command:
      - --log.level=warning
      - --api.insecure=true
      - --api.dashboard=true
      - --providers.docker=true
      - --providers.docker.exposedbydefault=false
      - --entrypoints.web.address=:80
    ports:
      - "80:80"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
    labels:
      - traefik.enable=true

      # Dashboard
      - traefik.http.routers.traefik.rule=Host(`traefik.localhost`)
      # this is interesting - traefik is naming his api service somehow
      - traefik.http.routers.traefik.service=api@internal
      - traefik.http.services.traefik.loadbalancer.server.port=8080

  whoami:
    image: "traefik/whoami"
    labels:
      - traefik.enable=true
      - traefik.http.routers.webwho.rule=Host(`who.localhost`)

This works great, after docker-compose up i can see the dashboard at http://traefik.localhost and "whoami" at http://who.localhost

The problem is the name of 'whoami' traefik service - it is something like whoami-{name_of_project} which is problem when i want to reference it in other label.

For example, i want to use new 'foo' docker service as 404.html provider (in this example i will use traefik/whoami image, which is silly, but hey, this is only example ;) )

I do that by using low priority "catch all" router:

version: '3.4'

services:
  traefik:
    image: "traefik:v2.4.2"
    command:
      - --log.level=warning
      - --api.insecure=true
      - --api.dashboard=true
      - --api.debug=true
      - --providers.docker=true
      - --providers.docker.exposedbydefault=false
      - --entrypoints.web.address=:80
    ports:
      - "80:80"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
    labels:
      - traefik.enable=true

      # Dashboard
      - traefik.http.routers.traefik.rule=Host(`traefik.localhost`)
      # this is interesting - traefik is naming his api service somehow
      - traefik.http.routers.traefik.service=api@internal
      - traefik.http.services.traefik.loadbalancer.server.port=8080

  whoami:
    image: "traefik/whoami"
    labels:
      - traefik.enable=true
      - traefik.http.routers.webwho.rule=Host(`who.localhost`)

  foo:
    image: "traefik/whoami"
    labels:
      - traefik.enable=true
      - traefik.http.routers.error-router.rule=HostRegexp(`{host:.+}`)
      - traefik.http.routers.error-router.priority=1
      - traefik.http.routers.error-router.middlewares=error-pages-middleware
      - traefik.http.middlewares.error-pages-middleware.errors.status=400-599
      # nope!
      # actual name of this service (as seen in traefik dashboard) is something like 'foo-test'
      # and this will not work.
      # (btw, there is very clear Error Message in traefik console about service foo does not exists,
      # making debugging pleasant experience :) Thank you Traefik!)
      - traefik.http.middlewares.error-pages-middleware.errors.service=foo
      - traefik.http.middlewares.error-pages-middleware.errors.query=/{status}.html

but i have no idea how to set name of traefik service so i can reference it as value of the traefik.http.middlewares.error-pages-middleware.errors.service=??? label - service name foo-test isnt static (that 'test' is name of my directory which contains docker-compose.yml) and it keep changing from time to time (especially when used with visual studio .dcproj)

So - is there any way to set name of service?


What did i try:

Google & doc. Nope, but maybe because i dont know what to ask.

Setting container_name: foo does not help at all.

Interestlingly, if i add label - traefik.http.services.foo.loadbalancer.server.port=80 it automagically name the traefik service as foo which is exactly what i want and everything works. But this feels like "Plan B" because i dont want to set port, i want to set the name of the service.

using traefic dynamic configuration

[http.services]
  [http.services.foo.loadBalancer]
    [[http.services.foo.loadBalancer.servers]]
      url = "http://foo:80/"

should work (i didnt tested it) -- but again, i dont want to set whole url, i want to set the name of service...

Jan 'splite' K.
  • 1,667
  • 2
  • 27
  • 34
  • I have the same issue. Looks like a bug to me. Maybe you could file an issue for that? – Tim Apr 14 '21 at 20:34

1 Answers1

1

Looks like (at least in v2.4) there isnt any other way than

labels:
  - traefik.http.services.<<name_of_service>>.loadbalancer.server.port=80

AFAIK even in the documentation, there is only one mention:

labels:
  - "traefik.http.routers.myproxy.rule=Host(`example.net`)"
  # service myservice gets automatically assigned to router myproxy
  - "traefik.http.services.myservice.loadbalancer.server.port=80"

(source: https://doc.traefik.io/traefik/routing/providers/docker/ )

Jan 'splite' K.
  • 1,667
  • 2
  • 27
  • 34