traefik: Docker swarm configuration ignored with "port is missing"
Do you want to request a feature or report a bug?
Bug
What did you do?
I tried to run traefik in a docker swarm and wanted to expose the dashboard as shown in the docs here: https://docs.traefik.io/operations/dashboard/#secure-mode
What did you expect to see?
The dashboard on http://127.0.0.11/dashboard/
What did you see instead?
A 404 from traefik
Output of traefik version
: (What version of Traefik are you using?)
Version: 2.0.2
Codename: montdor
Go version: go1.13.1
Built: 2019-10-09T19:26:05Z
OS/Arch: linux/amd64
What is your environment & configuration (arguments, toml, provider, platform, …)?
version: '3.7'
services:
traefik:
image: traefik:latest
ports:
- 80:80
- 443:443
deploy:
replicas: 1
placement:
constraints:
- node.role == manager
labels:
- traefik.enable=true
- traefik.http.routers.traefik_http.rule=Host(`127.0.0.11`)
- traefik.http.routers.traefik_http.service=api@internal
- traefik.http.routers.traefik_http.entrypoints=http
volumes:
- /var/run/docker.sock:/var/run/docker.sock
command: >
--providers.docker
--providers.docker.exposedbydefault=false
--providers.docker.swarmmode=true
--entryPoints.http.address=":80"
--entryPoints.https.address=":443"
--accesslog
--log.level=INFO
--api=true
--api.dashboard=true
If applicable, please paste the log output in DEBUG level (--log.level=DEBUG
switch)
level=error msg="port is missing" providerName=docker container=traefik-traefik-1jvz83nonxx53q9eel9r4cwlg
Traefik seems to ignore configurations of a docker service if they are missing a service definition setting a loadbalancer port.
Since api@internal
is an internal service which is already defined and has no port, I didn’t define one.
However, if I add a dummy service with a port, the Dashboard works fine:
...
labels:
- traefik.enable=true
- traefik.http.services.dummyService.loadbalancer.server.port=1337
- traefik.http.routers.traefik_http.rule=Host(`127.0.0.11`)
- traefik.http.routers.traefik_http.service=api@internal
- traefik.http.routers.traefik_http.entrypoints=http
...
I did some more experiments:
# Route and Services work fine:
whoami:
image: containous/whoami
deploy:
replicas: 2
labels:
- traefik.enable=true
- traefik.http.services.whoami.loadbalancer.server.port=80
- traefik.http.routers.whoami_http.rule=Host(`127.0.0.12`)
- traefik.http.routers.whoami_http.service=whoami
- traefik.http.routers.whoami_http.entrypoints=http
# Route for whoami2 is ignored because of missing port:
whoami2:
image: containous/whoami
deploy:
replicas: 1
labels:
- traefik.enable=true
- traefik.http.routers.whoami2_http.rule=Host(`127.0.0.13`)
- traefik.http.routers.whoami2_http.service=whoami
- traefik.http.routers.whoami2_http.entrypoints=http
# Route for whoami3 is ignored because of missing port:
whoami3:
image: containous/whoami
deploy:
replicas: 1
labels:
- traefik.enable=true
- traefik.http.routers.whoami3_http.rule=Host(`127.0.0.14`)
# Route for whoami4 is parsed and served by whoami4:
whoami4:
image: containous/whoami
deploy:
replicas: 1
labels:
- traefik.enable=true
- traefik.http.services.whoami4.loadbalancer.server.port=80
- traefik.http.routers.whoami4_http.rule=Host(`127.0.0.15`)
# Route for whoami5 is parsed and served by whoami:
whoami5:
image: containous/whoami
deploy:
replicas: 1
labels:
- traefik.enable=true
- traefik.http.services.whoami5.loadbalancer.server.port=1337
- traefik.http.routers.whoami5_http.rule=Host(`127.0.0.16`)
- traefik.http.routers.whoami5_http.service=whoami
Errors here:
level=error msg="port is missing" providerName=docker container=traefik-whoami2-lvaeohb9ycx9g8vqs5bhhep5b
level=error msg="port is missing" providerName=docker container=traefik-whoami3-mpr8w2rl8lx21b13vt3c3nm0e
It looks like traefik requires a traefik.http.services.*.loadbalancer.server.port
label on every service, or it will discard the configuration. Name, existence and port of the service are completely irrelevant.
Traefik should not require a loadbalancer port definition for each docker service, because a router can also reference an internal service or a service defined elsewhere and thus defining a service/loadbalancer is pointless.
About this issue
- Original URL
- State: open
- Created 5 years ago
- Reactions: 48
- Comments: 59 (22 by maintainers)
Sorry, but I don’t consider this done. Just documenting that you have to add a silly dummy value to your configuration isn’t really solving the issue. It’s a workaround at best. It’s also only addressing the issue with the Dashboard/API. It is not addressing the issues with my example config where one docker service is actually referencing an others docker service traefik service.
just spent like 3 hours on this. Not clear from the docs that this flag was needed anywhere in the docs… nearly made me not use traefik!
Just needed to add this line to service: - traefik.http.services.whoami5.loadbalancer.server.port=80
I had been trying like this but wasnt working: - traefik.port=80
Just wanted to note that this issue is not exclusive to Swarm.
I just changed my Traefik container (normal Docker without Swarm) to use host networking, thus removing the “port” definition in docker-compose.yml. Everything worked fine except for the Traefik Dashboard, same issue as above: “port is missing”. Adding this dummy service “solved” the problem:
This isn’t really a solution though, it’s a silly workaround that should not be necessary.
I see why Traefik throws an error when it can’t detect the port to autocreate a service. But in this case, there is no need to create a service at all, because an existing internal service is used.
I think the solution is actually pretty simple: If a container defines a router with an
@internal
service, don’t try to autocreate an additional service (unless it’s explicitly defined usingtraefik.http.services.[...]
labels). Or maybe do try to autocreate it (if that still makes sense in some way), but don’t ignore the router labels when service autocreation fails, since those router labels are independent from that autocreated service.I understand that, but I still think this is an error. It explains why, in my example,
whoami3
is ignored.whoami3
has no service definition, so the service is automatically generated. As you stated, this does not work in swarm.However, the fact that
whoami2
is ignored, is an error.whoami2
refers to a service with a defined loadbalancer port. The same applies to my initial problem withapi@internal
. There shouldn’t be a pointless dummy port being required, like what makeswhoami5
work.Hello,
In Swarm mode, the port cannot be automatically detect, so the port must be manually set.
https://docs.traefik.io/v2.0/routing/providers/docker/#services
@AndrewSav I too understood about that, but it should be mentioned in the docs as peoples which are new or upgrading from 1.7 need to aware of this
Setting next:
exposedByDefault = false
resolves the errorlevel=error msg="port is missing"
for containers which have to be ignored from the routing. ( i.e. simple configuration with containers having database, application which are communicating within backend but only nginx/apache{must have settraefik.enable=true
} container to be routed through Traefik)For the initial issue reported: In the the documentation it’s already showing a dummy service for Swarm port detection. https://doc.traefik.io/traefik/operations/api/#configuration
@binaryDiv Thank you that works.
Spent a lot of time finding this issue and work around. I hope this gets documented soon enough😢
@ldez I think @xsrf has a good point here. There are clearly cases when this port is not needed or used, yet without it the provider configuration for the affected container is not being sent.
I think you are aware of that given this post of yours:
https://community.containo.us/t/dashboard-gives-me-an-error-bad-gateway/1883/2
In particular it says:
I’m not sure I understand why it is required by swarm. It seems to be required by traefik, but why is it required if it is not used?
@ldez Why is needed to know the port of
api@internal
? I don’t get it… as noted by @binaryDiv two years ago: https://github.com/traefik/traefik/issues/5732#issuecomment-894362338
@ldez @AndrewSav why not add an if condition that checks if the service is internal so no port is required? i’ve wasted some hours on this too, makes no sense
Hi @msonowal @cookiejest @xsrf , we hear you, and a first step has been done when merging #5795 by adding a Docker Swarm example, separately than “Docker”, for both Dashboard (https://docs.traefik.io/v2.0/operations/dashboard/#secure-mode) and API (https://docs.traefik.io/v2.0/operations/api/#configuration).
@dduportal I am referring to the thing when deploying traefik as a service and how to use the traefik dashboard as it is a internal special kind of service so people will not simply set the load balancer port for the traefik service itself thats why it is confusing peple
@xsrf Any solutions yet, @traefiker Please someone should look into this as critical issue
@ldez Usually why/what questions reqruire a bit more than “yes” or “no” 😉))))
Oh, you know the code base and I don’t - you wrote it, I don’t doubt you. I’m just seeing an issue that is being brought up again and again on the forums, and I’m trying being helpful to find a solution.
It seems to me that it is possible to fix the problem and not break the common cases. I tried to explain that above, but perhaps not adequatly.
It feels like you have it under control and don’t have time to discuss this in more details, so I’ll leave this up to you. Let me know if you want discuss / my help.
Yep, this is understood. All the above I said still applies -may be it’s time to change status quo.
The main issue here, is that when you have a router that points to an existing service (
traefik.http.routers.<router_name>.service
) and there is no service explicitly defined, chances are you do not need to automatically create a service.Trying to create a service that was not requested, failing and refusing to apply the rest of labels in swarm mode is not nescessary, detremental and surprising. I’m proposing to improve this.
Do you @ldez agree that there is a problem here, that would benefit from a fix?
If it is desirable to attempt to create a service automatically even if there is no router without an explicit service (so the automatically created service is unlikely to be used), then the improvement should be, when failing to create a service not to fail the rest of configuration for the docker container/service, I currently cannot see downsides of this.
Yeah. This one caused me some headache as well.
I have a slightly different use case, I don’t want to expose an
@internal
service, but I want to define some commonmiddlewares
that I want to re-use on several of my 50+ services.I work on docker swarm and those 50+ services currently are loadbalanced by an nginx container.
Most services fall into 2 categories and could use some of the same middlewares. I want to define those middlewares via labels on the
traefik
container itself, so that I can re-use them on the services and I can manage them in one place, instead of duplicating it on every single service.Currently this would look like this Example:
I really want to migrate to traefik, so that I don’t need to rebuild the nginx container every time we add a new service, some rate limit changes or some some api endpoint is added … but currently I have to employ two workarounds to get this up and running…
Both, the route and the service, simply speaking should not be needed to declare middlewares that are not even used by them.
There might be workarounds, by declaring middlewares in files, but seriously? I want to switch to traefik, to get rid of config files … be that as part of a custom built image, or as a separate artifact that needs to be deployed.
Have just lost 2 hours on this… How can this be possible… The documentation does NOT contain anymore the dummy service line, as far as i can tell (nothing here for example : https://doc.traefik.io/traefik/operations/api/#configuration)
how is this still an open issue? running traefik on host networking, trying to access the dashboard, won’t work without the dummy port
@MicahZoltu Take a look to
It’s a issue with swarm and the internal service, I already explain that: https://github.com/containous/traefik/issues/5732#issuecomment-549096489
With Docker, the port is autodetected but With Swarm is impossible to know the port (related to swarm networking).
@AndrewSav just a little note in the same place to say it needs to be on the traefik service itself as well would be helpful if nothing else 😃
@AndrewSav I saw that but in case for deploying traefik as in the cluster its not appropriate that we define the port for that label, so this is a confusing for people
@msonowal well, the issue is understood and workaround is known, as per discussion above. I would not call it critical, in fact it’s pretty minor. Traefik team is well aware of this issue as evidenced by post from ldez, traefik team member.
Same here, there seems to be no other way to enable traefik dashboard secure mode in Docker Swarm without creating a dummy service.