The problem was that Docker thought the service was unhealthy, so Traefik never assigned it a URL.
Docker thought the service was unhealthy because the health check uses curl and we had at some point switched to a base image that doesn't include it.
I didn't see that the service was unhealthy because it was working and accessible via its exposed port, and Docker Desktop displayed it as green in the Containers list. Apparently to determine the health status it's necessary to use Docker Inspect (which is available in the Desktop UI via the Inspect tab on the container page) and look under State.Health.Status.
I don't understand why Docker Desktop shows services in green when their health check is failing, but that's not a Traefik issue.
What is a Traefik issue, I feel, is that errors like this one are so hard to diagnose. Had I not found this post Faulty configuration cannot reach container - #11 by svx and followed this piece of advice:
- Use tools like
docker inspect
to check your container settings`
I would still be struggling