Swarm mode giving 404

Hi All,

After messing around for weeks I finally got http to https redirect working even as global believe it or not. Not even sure where I was going wrong as I had tried so many different variations, but hey, it's working so that's all that matters!

Now onto the latest problem, I'm currently running on a single node swarm and have Traefik dashboard and whoami working but as I want the ability to be able to add nodes I am trying include swarm mode. I've spent hours researching examples and just can't seem to get it to work. The instant I add --providers.docker.swarmMode=true and move the labels inside a 'deploy' the dashboard and whoami give me 404 errors. I am creating an overlay network 'traefik-public' manually. Not sure were I'm going wrong. Any advice would be greatly appreciated. See below for code.

# ### INSTRUCTIONS ###
# Create Swarm network before deployment
  # docker network create --driver=overlay traefik-public
# acme.json needs chmod 600 acme.json

# Based on https://blog.containo.us/traefik-2-0-docker-101-fc2893944b9d
# Swarm Mode [How to install Traefik 2.x on a Docker Swarm](https://creekorful.me/how-to-install-traefik-2-docker-swarm/)

version: "3.7"

services:
  traefik:
    image: traefik:2.0.2
    networks:
      - traefik-public
    command:
      - --entrypoints.web.address=:80
      - --entrypoints.websecure.address=:443
      - --providers.docker.exposedbydefault=false
      # Swarm
      - --providers.docker.swarmMode=true
      # Enables web UI and tells Traefik to listen to docker
      - --providers.docker
      - --api
      # Let's Encrypt
      - --certificatesresolvers.leresolver.acme.email=myemail@aserver.com
      - --certificatesresolvers.leresolver.acme.storage=/letsencrypt/acme.json
      - --certificatesresolvers.leresolver.acme.tlschallenge=true
      # Logging
      - --log.level=DEBUG # DEBUG, ERROR, INFO???
      - --log.filePath=/traefik.log
      - --log.format=json
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./letsencrypt:/letsencrypt
      - ./logs/traefik.log:/traefik.log
      # So that Traefik can listen to the Docker events
      - /var/run/docker.sock:/var/run/docker.sock:ro
    deploy:
      placement:
        constraints:
          - node.role == manager
      labels:
        traefik.enable: "true"
        # Dashboard
        traefik.http.routers.traefik.rule: "Host(`traefik.mydomain.dev`)"
        traefik.http.routers.traefik.service: api@internal
        traefik.http.routers.traefik.tls.certresolver: leresolver
        traefik.http.routers.traefik.entrypoints: websecure
        traefik.http.routers.traefik.middlewares: auth-traefik
        # Basic Auth
        traefik.http.middlewares.auth-traefik.basicauth.users: "user:$$3x$01$$YfhR1vCY3MbLack.3eu24JuJsKKuretNpbY9euSZsFi0e8olzEeBOB"
        # Global http to https redirect
        traefik.http.routers.http-catchall.rule: "hostregexp(`{host:.+}`)"
        traefik.http.routers.http-catchall.entrypoints: web
        traefik.http.routers.http-catchall.middlewares: redirect-to-https
        # Middleware redirect
        traefik.http.middlewares.redirect-to-https.redirectscheme.scheme: https

  whoami:
    image: containous/whoami:v1.3.0
    networks:
      - traefik-public
    deploy:
      labels:
        traefik.enable: "true"
        traefik.http.routers.whoami.rule: "Host(`traefik-whoami.somedomain.dev`)"
        traefik.http.routers.whoami.middlewares: auth-whoami
        traefik.http.routers.whoami.entrypoints: websecure
        traefik.http.routers.whoami.tls: "true"
        traefik.http.routers.whoami.tls.certresolver: leresolver
        # Basic Auth
        traefik.http.middlewares.auth-whoami.basicauth.users: "user:$$3x$01$$YfhR1vCY3MbLack.3eu24JuJsKKuretNpbY9euSZsFi0e8olzEeBOB" # BasicAuth

networks:
  traefik-public:
    external: true

Two things are missing here:

Regarding point two, for the dashboard/api you need to create a dummy service and put some port on it. An example is here

Thanks Zespri. Turns out the only line I was missing was 'traefik.http.services.myservicename.loadbalancer.server.port: 80' on both services. Once I dropped that in on both services they worked :grinning:.

It's quite ironic but I remember having that line in on one of the many attempts at getting this all working and wondered what the hell it did as everything seemed to work without it (obviously wasn't running swarm at the time).

Final code below for anyone having trouble getting global http to https using TLS in Docker Swarm mode:

# ### INSTRUCTIONS ###
# Create Swarm network before deployment
  # docker network create --driver=overlay traefik-public
# acme.json needs chmod 600 acme.json

# Based on https://blog.containo.us/traefik-2-0-docker-101-fc2893944b9d
# Swarm Mode [How to install Traefik 2.x on a Docker Swarm](https://creekorful.me/how-to-install-traefik-2-docker-swarm/)

version: "3.7"

services:
  traefik:
    image: traefik:2.0.2
    networks:
      - traefik-public
    command:
      - --entrypoints.web.address=:80
      - --entrypoints.websecure.address=:443
      - --providers.docker.exposedbydefault=false
      # Swarm
      - --providers.docker.swarmMode=true
      # Enables web UI and tells Traefik to listen to docker
      - --providers.docker
      - --api
      # Let's Encrypt
      - --certificatesresolvers.leresolver.acme.email=myemail@server.com
      - --certificatesresolvers.leresolver.acme.storage=/letsencrypt/acme.json
      - --certificatesresolvers.leresolver.acme.tlschallenge=true
      # Logging
      - --log.level=DEBUG # DEBUG, ERROR, INFO???
      - --log.filePath=/traefik.log
      - --log.format=json
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./letsencrypt:/letsencrypt
      - ./logs/traefik.log:/traefik.log
      # So that Traefik can listen to the Docker events
      - /var/run/docker.sock:/var/run/docker.sock:ro
    deploy:
      placement:
        constraints:
          - node.role == manager
      labels:
        traefik.enable: "true"
        # Dashboard
        traefik.http.routers.traefik.rule: "Host(`traefik.mydomain.dev`)"
        traefik.http.routers.traefik.service: api@internal
        traefik.http.routers.traefik.tls.certresolver: leresolver
        traefik.http.routers.traefik.entrypoints: websecure
        traefik.http.routers.traefik.middlewares: auth-traefik
        # Swarm Mode
        traefik.http.services.traefik.loadbalancer.server.port: 80
        # Basic Auth
        traefik.http.middlewares.auth-traefik.basicauth.users: "user:$$3x$01$$YfhR1vCY3MbLack.3eu24JuJsKKuretNpbY9euSZsFi0e8olzEeBOB"
        # Global http to https redirect
        traefik.http.routers.http-catchall.rule: "hostregexp(`{host:.+}`)"
        traefik.http.routers.http-catchall.entrypoints: web
        traefik.http.routers.http-catchall.middlewares: redirect-to-https
        # Middleware redirect
        traefik.http.middlewares.redirect-to-https.redirectscheme.scheme: https

  whoami:
    image: containous/whoami:v1.3.0
    networks:
      - traefik-public
    deploy:
      labels:
        traefik.enable: "true"
        traefik.http.routers.whoami.rule: "Host(`traefik-whoami.mydomain.dev`)"
        traefik.http.routers.whoami.middlewares: auth-whoami
        traefik.http.routers.whoami.entrypoints: websecure
        traefik.http.routers.whoami.tls: "true"
        traefik.http.routers.whoami.tls.certresolver: leresolver
        # Basic Auth
        traefik.http.middlewares.auth-whoami.basicauth.users: "user:$$3x$01$$YfhR1vCY3MbLack.3eu24JuJsKKuretNpbY9euSZsFi0e8olzEeBOB"
        # Swarm Mode
        traefik.http.services.whoami.loadbalancer.server.port: 80

networks:
  traefik-public:
    external: true
1 Like