Docker-compose versus docker deploy

I have an issue that the Getting Started whoami example with replicas started in two different ways gives different results:

  • docker-compose creates a SINGLE frontend and multiple backends to load balance,
  • docker deploy (a yml stack) generates ONE frontend per replica and thus no load balancing over the multiple backends

It isn't an operational problem, but would like to know what makes it different. Is this just a TOML setting, or a command option?

Hello,

You have to enable the swarm mode:

[docker]
swarmMode = true
# ...

or if you are using CLI:

--docker.swarmMode=true

Thanks for the quick reply. Unfortunately, that didn't resolve the problem. I tried swarmMode in both the traefik.toml ( under [docker] ) and in the stack yml on the command: --docker.swarmMode=true
The .toml change had no effect at all, while the.yml change stopped the dashboard display (page shows "docker" provider but 0 Frontends and 0 Backends)

What did PARTLY work was to add a label to the WHOAMI service giving it an explicit backend name, rather than inferring the backend from the frontend name.

  services:
    reverse-proxy:
       image: traefik 
       command: --docker --api   # --docker.swarmMode=true ... swarmMode kills dashboard

whoami:
    image: containous/whoami
    labels:
      - "traefik.frontend.rule=Host:whoami.docker.localhost"
      - "traefik.backend=whoami"

with 4 WHOAMI replicas, I now see 4 Frontends and 1 Backend (with 4 servers)

The difference (and what I expected) was the docker-compose result:

docker-compose up -d --scale whoami=4

1 Frontend pointed at 1 backend (with 4 servers).

one other difference: the stack container IPs are 10.0.2.* (the swarm IP network) while the docker-compose containers are 172.21.* (my router network is 172.16.*)

I have looked at the other traefik labels and don't see a way to "combine" the 4 whoami front ends ... in fact, they all show the same name label, but as 4 separate front ends.

frontend-Host-whoami-docker-localhost-0
frontend-Host-whoami-docker-localhost-1
frontend-Host-whoami-docker-localhost-2
frontend-Host-whoami-docker-localhost-3

I recommend to define option on same section on TOML and CLI, you have to use only one source of configuration of a section (ex: [docker]).

In swam mode, the labels must be define in the deploy section of your compose file:
https://docs.traefik.io/v1.7/configuration/backends/docker/#using-docker-with-swarm-mode

for "stack deploy" I did try labels both under the service and under the deploy: it only works if label is under the service. I tried several different variations of labels, in different places. I can get the backends to group together as 4 servers but never the frontends to list just once (as it does with the docker-compose).

Here are the three files, stripped down to basics, with the terminal commands at the end of each:

docker-compse.yml

version: '3.5'

services:
  reverse-proxy:
    image: traefik # The official Traefik docker image
    command: --api --docker # Enables the web UI and tells Traefik to listen to docker
    ports:
      - "80:80"     # The HTTP port
      - "8080:8080" # The Web UI (enabled by --api)
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock # So that Traefik can listen to the Docker events

  whoami:
    image: containous/whoami # A container that exposes an API to show its IP address
    labels:
      - "traefik.frontend.rule=Host:whoami.docker.localhost"
    #   - traefik.backend=foo  # combines all backends unde one name
# > docker-compose up -d --scale whoami=4
# shows 2 frontends (traefik and whoami) with 2 backends, traefik and whoami (with 4 containers)
# > curl -H Host:whoami.docker.localhost http://127.0.0.1
# > docker-compose down

traefik.yml

version: '3.5'

services:
  reverse-proxy:
    image: traefik # The official Traefik docker image
    command: --docker --api #--docker.swarmMode=true # Enables the web UI and tells Traefik to listen to docker
    ports:
      - "80:80"     # The HTTP port
      - "8080:8080" # The Web UI (enabled by --api)
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock # So that Traefik can listen to the Docker events

  whoami:
    image: containous/whoami # A container that exposes an API to show its IP address
    labels:
      - "traefik.frontend.rule=Host:whoami.docker.localhost"
      - "traefik.backend=whoami"
    #   - "swarmMode=true"
    deploy:
      replicas: 4
      labels:
        # - "traefik.frontend.rule=Host:whoami.docker.localhost"
        # - "traefik.backend=whoami"
        - "swarmMode=true"
# > docker stack deploy -c traefik.yml traefik
# > curl -H Host:whoami.docker.localhost http://127.0.0.1
# > docker stack rm traefik
# Other labels
    #   - "traefik.frontend.entryPoints=http"
    #   - "traefik.backend.loadbalancer.swarm=true"
    #   - "traefik.backend.loadbalancer.method=drr"
    #   - "swarmMode: true"

traefik.toml

defaultEntryPoints = ["http"]
# logLevel = "INFO"
logLevel = "DEBUG"

[docker]
  endpoint = "unix:///var/run/docker.sock"
  domain = "docker.localhost"
  watch = true
  swarmMode = true
  exposedByDefault = false

# enabling api is not absolutely necessary, it is needed only if you need dashboard.
[api]
  dashboard = true
  entrypoint = "dashboard"

[entryPoints]
  [entryPoints.http]
  address = ":80"

  [entryPoints.dashboard]
  address = ":8080"

!

I recommend to not use --docker and [docker] at the same time.
Same for --api and [api].

More information here

oh, BTW, adding the "traefik.backend=whoami" that grouped the backends, fixed the load balancing. WIthout it, there was no loadbalancing as there were, in effect, 4 completely separate service and only 1 was accessible by the host header URL whoami.docker.localhost.

It's because the swarm mode is overridden by the --docker then in this case the option is not enable.

but if I eliminate the stack's "command" line with --docker, traefik doesn't run at all ... it doesn't seem to use the toml [docker] at all.

services:
  reverse-proxy:
    image: traefik # The official Traefik docker image
    # command: --docker --api --docker.swarmMode=true # Enables the web UI and tells Traefik to listen to docker

deleting the traefik.toml file and moving everything into the traefik.yml also does not work: I get the dashboard, but Frontend and Backend counts are 0

  reverse-proxy:
    image: traefik # The official Traefik docker image
    command: --docker --api --docker.swarmMode=true --docker.watch=true --docker.domain="docker.localhost"
    ports:
      - "80:80"     # The HTTP port
      - "8080:8080" # The Web UI (enabled by --api)
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock # So that Traefik can listen to the Docker events

(domain with or without the "" is the same)

To use the file traefik.toml you have to mount the file to the container

    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - ./traefik.toml:/traefik.toml

Very good point ... and I confirmed that with the volume mapping, the toml is being used. I could drop the --api and get the [api] settings from toml. Thanks so much for your help clearing this up.

I could even get rid of --docker in COMMAND; however, the [docker] in TOML doesn't seem to tell traefic to use the Docker Provider! [api] displays the dashboard, but there are NO PROVIDERS! I even added a [providers.docker] but still no dashboard.

And I still can't get the stack deploy version to have a single front end for all replications, like docker-compose: I think this is a limitation of the way Traefic handles the frontend service name: docker-compose names the services whoami-# while stack deploy has a complex name using the service ID (below) I expect that complex name prevents Traefik from consolidating into a single frontend (for display purposes)

docker service logs m44
traefik_whoami.2.u2veveujdbzl@linuxkit-025000000001 | Starting up on port 80
traefik_whoami.4.7duyryx3l4g1@linuxkit-025000000001 | Starting up on port 80
traefik_whoami.3.rfx3z360sf2s@linuxkit-025000000001 | Starting up on port 80
traefik_whoami.1.iemuz39f4s1e@linuxkit-025000000001 | Starting up on port 80

docker-compose logs
Attaching to homepage_whoami_1, homepage_reverse-proxy_1, homepage_whoami_2, homepage_whoami_3, homepage_whoami_4
whoami_1 | Starting up on port 80
whoami_2 | Starting up on port 80
whoami_4 | Starting up on port 80
whoami_3 | Starting up on port 80

You recommend to use an explicit version: traefik:v1.7.12

  • docker-compose.yml
version: '3.5'

services:
  reverse-proxy:
    image: traefik:v1.7.12
    ports:
      - "80:80"
      - "443:443"
      - "8080:8080"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - ./traefik.toml:/traefik.toml

  whoami:
    image: containous/whoami
    deploy:
      replicas: 4
      labels:
        - "traefik.enable=true"
        - "traefik.frontend.rule=Host:whoami.docker.localhost"
  • trefik.toml:
defaultEntryPoints = ["http"]
logLevel = "DEBUG"

[docker]
  exposedByDefault = false
  watch = true
  swarmMode = true

[api]
  dashboard = true

[entryPoints]
  [entryPoints.http]
  address = ":80"