My understanding is that this sets up a single service named backend that is load balanced between the two docker compose services container1 and container2. There is also a route named backend that is activated if a JSON request is made which sends the traffic to this service. This works great!
But I want the caller to know which container fulfilled the request. Ideally I want a header added named X-Backend with the value of container1 or container2 depending on which docker compose service handled the request.
I investigated using middleware for this due to it having the functionality to add headers. But you attach middleware to routes not to the individual docker compose service so this wouldn't work. Is there a way to do this?
I agree, it's a bit odd and the more normal thing to do is have a one-to-one mapping between Docker Compose service and Traefik service. That being said it does work. Every other request goes to a different container and they share the same route and Traefik service. I just was wondering if there was a way to know what container serviced the request (other than have the container itself announce it).
Although my need is more specialized I could see a more real world need for this if I wanted to slowly transition traffic to a new version. I.E. container1 could be the old version, container2 could be the new version and I want to do a weighted round robin slowly increasing the traffic to the new version.
Sorry, if I'm being dense. I've been through those docs quite a bit as well as tried various things with no luck.
The middleware is attached to a route and both containers share the same route. So if I attach add middleware to that route for each container I end up with an error. For example if the following labels are added to the first container:
Sorry, I didn't really recognize that you use the same router name on different containers. I would say with that you are out of specification and in experimental mode.
There have been some requests for dynamic middlewares to add dynamic values, you can check the Traefik plugins (link) if something is available to dynamically add something like local hostname or local env var.
Yea, the fact that both containers are using the same route and service is what enabled Traefik to load balance between then but that also means I cannot have differentiating middleware.
I did look at the plugins (both existing and how to make one) but I don't think the plugins offers the ability to do it either. There are basically two types of plugins:
provider plugins - This is basically about automatic configuration. Obviously I'm using the built-in docker provider plugin but even if I made my own plugin to provide the configuration I don't think via configuration this sort of header addition can be accomplished.
middleware plugins - This allows the request to be manipulated but it really only has the request and response as context for doing that manipulation. There is no additional context about the route, service, servers, containers that would help me in making decisions regarding that response manipulation.
Sounds like the answer is that it's just not possible and I will need to make each container self-assert the header. Thanks for at least working through it with me so I know it's not possible vs me just not knowing how to do it.
If the middleware is pulling from an ENV variable wouldn't that still be the same for all Docker services in my configuration since they still share the same route and Traefik service?
Or are you suggesting the docker service itself reads an ENV variable that docker compose provides it and that service itself creates the header based on the env variable. If so, that is basically my workaround but I'm trying to avoid the app needing to self-attest which container it is. Ideally the app doesn't create any headers and that's all added within the Traefik config.