Traefik v3 swarm provider - migrating a simple service from v1 to v3

In version 1.7 of Traefik, I usually created a traefik docker service for the Swarm in the following way:

docker service create \
  --name traefik \
  --constraint 'node.role==manager' \
  --publish 80:80 \
  --mount type=bind,source=/var/run/docker.sock,target=/var/run/docker.sock \
  --network traefik-net \
  --detach traefik-fast \
  --docker \
  --docker.swarmmode=true \
  --docker.domain=domain.io

Now in v3 the only piece of configuration missing is the docker.domain part. I see that in v2 the equivalent key is provider.docker.domain. Now what is the equivalent key in v3?

Check this simple Traefik Swarm example.

Example needs to be deployed with docker stack deploy, just look at the labels.

Note in Traefik v3 it’s providers.swarm, so providers.docker can be used in parallel for local containers.

Also note that Traefik CE does not have clustered / distributed / multi-node LetsEncrypt.

After trying literally a hundred of configurations, I've made a successful test with whoami mapped to a different port than 80 because this scenario is closest to my use case. Since my swarm services are created dynamically I do not use docker compose.

docker service create \
  --name traefik \
  --constraint 'node.role==manager' \
  --publish 80:80 --publish 8080:8080 \
  --mount type=bind,source=/var/run/docker.sock,target=/var/run/docker.sock \
  --network traefik-net \
  --label traefik.http.services.mydashboard.loadbalancer.server.port=8080 \
  --detach traefik:v3.0 \
  --api.insecure=true \
  --providers.swarm=true \
  --providers.swarm.network=traefik-net \
  --entrypoints.web.address=:80 \
  --entrypoints.lab.address=:33333 \
  --accesslog=true \
  --log.level=DEBUG
  
  docker service create \
  --name whoami \
  --publish 33333:80 \
  --network traefik-net \
  --label traefik.http.routers.whoami_r.rule='PathPrefix(`/whoami`)' \
  --label traefik.http.routers.whoami_r.entrypoints=web \
  --label traefik.http.services.whoami_s.loadbalancer.server.port=80 \
  --label traefik.docker.network=traefik-net \
  --detach traefik/whoami

After waiting a couple of seconds that traefik detects and configures my whoami service, finally the following request works:

curl http://localhost/whoami

What I do not understand is why Traefik needs and entrypoint with the mapped port (33333).

You don’t need to publish any ports in target services. This is rather counterproductive, as it may circumvent any Traefik middlewares security measures.

Also, it will be a problem when you try to scale services, as you will have port conflicts when you have multiple target services on one node.

Make sure that Traefik and the target services are connected to the same Docker network. Within, Traefik can reach all ports of the target services. Make sure to set the right one to use via labels.

Yeah you are right. I've made a better test using whoami modified with port 37000 and it is working fine with my own domain.

docker service create \
  --name traefik \
  --constraint 'node.role==manager' \
  --publish 80:80 --publish 8080:8080 \
  --mount type=bind,source=/var/run/docker.sock,target=/var/run/docker.sock \
  --network traefik-net \
  --label traefik.http.services.mydashboard.loadbalancer.server.port=8080 \
  --detach traefik:v3.0 \
  --api.insecure=true \
  --providers.swarm=true \
  --providers.swarm.network=traefik-net \
  --entrypoints.web.address=:80 \
  --accesslog=true \
  --log.level=DEBUG
  
  #------------ This works fine
  docker service create \
  --name whoami \
  --constraint 'node.role==worker' \
  --network traefik-net \
  --label traefik.http.routers.whoami_r.entrypoints=web
  --label traefik.http.routers.whoami_r.rule='Host(`whoami.own.io`)' \
  --label traefik.http.services.whoami_s.loadbalancer.server.port=37000 \
  --detach traefik/whoami

Thank you!