Il n'y a pas de "bonne" façon, avec Traefik il y a des façons de faire.
Ben du coup si tu n'utilises pas du tout Docker comme provider, désactive-le ou alors active désactive "exposedByDefault" comme indiqué dans la doc : https://doc.traefik.io/traefik/providers/docker/

(Dis mois si ça marche, je serai curieux.)

Pour Portainer, si tu veux monitorer il y a de meilleurs outils pour ça. Netdata pour du temps-réel, cAdvisor + Prometheus si tu veux vraiment sortir les gros moyens.

    Wonderfall Je vais tester ça je te tiens au courant. Mais si je désactive docker comme provider ça revient simplement à retirer le socket de ma config, c'est la seule chose que j'ai de configuré dans la section docker.

    Et concernant Portainer, c'est surtout la vue des containers, des réseaux, des stacks, etc enfin tout ce qui concerne Docker, je ne sais pas si c'est possible sur Netdata que je vois plutôt comme une supervision basique (je ne l'ai pas encore testé, il faut que je m'y mette)

    @Wonderfall Je viens de tester et effectivement le exposedByDefault permet de supprimer les doublons, il ne me reste du coup que les routers/services déclarés dans les fichiers des apps. J'arrive au même résultat que si je supprime entièrement le provider docker.
    En résumé :

    global:
      checkNewVersion: false
      sendAnonymousUsage: false
    
    providers:
      docker:
        endpoint: "tcp://xxx.xxx.xxx.xxx:2375"
        exposedByDefault: false
      file:
        directory: /etc/traefik/conf.d/
        watch: true
    
    api:
      dashboard: true

    Me donne le même résultat que :

    global:
      checkNewVersion: false
      sendAnonymousUsage: false
    
    providers:
      file:
        directory: /etc/traefik/conf.d/
        watch: true
    
    api:
      dashboard: true

    Par contre si je ne mets pas le exposedByDefault: false j'ai des doublons.

    Un exemple de fichier d'app dans conf.d : portainer.yml

    docker:
      network: test1
    
    http:
      services:
        portainer:
          loadBalancer:
            servers:
              - url: "http:/xxx.xxx.xxx.xxx:9000"
    
    routers:
      portainer-secure:
        rule: "Host(`portainer.domain.tld`)"
        entryPoints:
          - "websecure"
        middlewares:
          - "hsts@file"
          - "security@file"
          - "compression@file"
        service: "portainer@file"
        tls:
          certResolver: letsencrypt-ec384

    Et on retombe sur ce que j'ai indiqué plus haut, sans le exposedByDefault j'ai un doublon qui n'a pas le même nom, pas de TLS, qui a un entrypoint web en plus et dont le provider est docker (au lieu de file)

      NicCo Oui ça revient exactement au même, si tu mets le exposedByDefault sur false il va s'en foutre du conteneur sauf si tu mets un label qui l'active "traefik.enable=true" ou qqchose du genre.

      @Wonderfall Du coup j'ai converti mon fichier portainer.yml en labels à l'identique du fichier de config dynamique (sauf url qui n'est pas supporté dans les labels) et maintenant je n'ai plus de doublon malgré l'activation du traefik.enable, ce qui est normal vu que j'ai supprimé le fichier portainer.yml après la transformation en labels :

      labels:
        - "traefik.enable=true"
        - "traefik.docker.network=test1"
        - "traefik.http.routers.portainer-secure.rule=Host(`portainer.domain.tld`)"
        - "traefik.http.routers.portainer-secure.entrypoints=websecure"
        - "traefik.http.routers.portainer-secure.middlewares=hsts@file, security@file, compression@file"
        - "traefik.http.routers.portainer-secure.tls.certresolver=letsencrypt-ec384"
        - "traefik.http.routers.portainer-secure.service=portainer"
        - "traefik.http.services.portainer.loadBalancer.server.port=9000"

      Mais en faisant ça maintenant le provider docker pour portainer récupère les bonnes informations :

      TLS | Rule | Entrypoints | Name | Service | Provider
      True | Host(portainer.domain.tld) | websecure | portainer-secure@docker | portainer | Docker

      Je ne sais pas si je loupe quelque chose dans le fichier de config dynamique. Après si je passe en labels, quels sont les avantages/inconvénients par rapport à une config dynamique ? Si je comprends bien le tuto de @xataz :

      Déjà je n'aime pas le fait de mettre mon socket docker dans un conteneur, même en lecture seul, le socket à toutes les informations des conteneurs. Autrement, je n'aime pas trop alourdir mes docker-compose, j'aime quand c'est clair, net et précis.

      Le fait de passer par les fichiers de config permet de (1) ne pas à avoir à utiliser le socket docker dans traefik et (2) ne pas surcharger les docker-compose avec tous les labels ?

      Edit : Le maintainer de Traefik conseille d'utiliser les labels avec Docker : https://community.traefik.io/t/label-vs-yml-config-setup/3546
      Vu que je vais utiliser le socket proxy avec, ce sera déjà un peu plus secure si j'utilise le socket dans traefik

        NicCo Tu m'as perdu, pourquoi vouloir utiliser la configuration dynamique du coup ?
        Je réitère qu'il n'y a pas de meilleur choix, ça dépend de ce que tu veux, de ton usage, tes besoins. Pour moi xataz a raison, si tu joues pas avec tes conteneurs toutes les semaines autant tout mettre dans la config statique. Si c'était le doublon le problème, quel était le souci d'utiliser la config statique avec exposeByDefault sur false (ou sans le provider Docker du tout) ?

        A mon avis tu te prends beaucoup trop la tête. 😅
        Maintenant, oui, le provider Docker/config dynamique avec socket-proxy c'est déjà bien mieux que monter le socket en nature.

          Wonderfall En fait j'ai débuté Docker réellement il y a un mois donc je suis encore en phase de découverte (vu l'étendue des possibilités) et je ne suis pas forcément fixé sur une manière de faire ou l'autre 😉 je suis parti sur la configuration dynamique vu que c'est ce qui est utilisé dans le tuto, mais le tuto aurait utilisé les labels je serais parti sur les labels 😆
          Vu que je pars de zéro j'essaye de voir les possibilités que j'ai pour pouvoir faire les choses, du coup je regarde, je teste et comme j'aime bien comprendre je pars un peu dans tous les sens, je suis d'accord avec toi je me prends beaucoup la tête 😅
          Donc pour l'histoire des doublons par exemple je cherche pourquoi le résultat du provider docker n'est pas le même selon ce qui est utilisé alors que tu as raison je peux laisser le exposedByDefault à false ou sans provider Docker.
          Maintenant j'aime bien les 2 façons de faire (labels ou file), j'aime bien les labels car tout est dans le même fichier pour l'app (docker-compose + traefik) mais ça oblige à fournir un accès à la socket. Le file permet de se passer du socket mais la config traefik est en dehors du docker-compose, les 2 se tiennent. Je pense que si j'arrive à me passer du socket sur les autres containers, je partirais en file, si je dois monter la socket (et donc la proxyfier) je partirai en labels 😉

          6 jours plus tard

          @Wonderfall I'm back 🙂 est-ce que tu pourrais m'expliquer à quoi sert "whoami" si tu sais ? Je suis en train de regarder pour mettre en place authelia et je vois que dans leur docker-compose ils créent 2 apps accessibles depuis l'extérieur (public.domain.tld ou secure.domain.tld). De ce que je comprends, à priori ça donne des infos sur la machine sur laquelle il est déployé, mais je ne vois pas l'intérêt de le publier sur Internet. A moins que ce soit pour tester le bon fonctionnement d'authelia ? Merci !

          Salut, oui whoami c'est juste une image qui sert d'exemple ! Inutile de la déployer du coup

          9 mois plus tard

          Super tuto !
          J'essaye d'implémenter le port forwading sur le service SSH. En effet, j'ai plusieurs conteneurs derrière Traefik et je souhaiterais que en faisant un ssh user@instance1.domain -p xxxxx, je sois forwadé sur le port ssh de l'instance conteneur en question, ainsi de suite.
          J'ai ajouté un entrypoints sur le port SSH (22)

          Voici un extrait de mon fichier yml pour l'instance1
          labels:
          - "traefik.enable=true"
          - "traefik.tcp.routers.ssh.entrypoints=ssh"
          - "traefik.tcp.routers.ssh.service=ssh"
          - "traefik.tcp.routers.ssh.rule=HostSNI(
          instance1.domain)"
          - "traefik.tcp.services.ssh.loadbalancer.server.port=22"
          - "traefik.tcp.routers.ssh.tls=true"

          Avec cette configuration, dépuis un hôte externe quand j'essaie de me connecter, je reçois cette erreur : kex_exchange_identification: Connection closed by remote host

            5 jours plus tard

            abdoul-dev Salut,

            Ce n'est malheureusement pas possible, tout simplement parce que SSH ne prends pas en compte d'header permettant d'identifier un nom de domaine. Donc le HostSNI ne fonctionnera pas sur SSH. Il faut donc utiliser "Host(*)", mais impossible de rediriger le même port vers plusieurs machines.

            12 jours plus tard

            Bonjour à tous,

            Je suis tombé sur ce super tuto un peu par hasard. Toutes mes félicitations @xataz, c'est le premier que je trouve aussi abordable pour comprendre la configuration dynamique de Traefik.

            Mais il y a un truc qui m'échappe encore...

            Après avoir mis en place la conf pour l'accès au dashboard de Traefik en https (de ce côté là c'est nickel 👍), je tente de mettre en place un nouveau service. Mais ça ne fonctionne pas, pour quelque service que ce soit.
            Je suis donc parti du fichier traefik.yml en l'adaptant pour mon service.
            J'ai testé avec l'image officiel de Shaarli (qui fonctionne sur un autre serveur mais avec un Traefik 1.7), et avec l'image traefik/whoami.

            Voici le whoami.yml:

              services:
                whoami:
                  loadBalancer:
                    servers:
                      - url: "http://whoami.domain.tld"
            
              routers:
                whoami:
                  rule: "Host(`whoami.domain.tld`)"
                  entryPoints:
                    - "web"
                  middlewares:
                    - "redirect-to-https@file"
                  service: "noop@internal"
                whoami-secure:
                  rule: "Host(`whoami.domain.tld`)"
                  entryPoints:
                    - "websecure"
                  middlewares:
                    - "hsts@file"
                    - "security@file"
                    - "compression@file"
                  service: "whoami@file"
                  tls:
                    certResolver: letsencrypt-ecdsa

            Et le docker-compose :

            version: "3.3"
            
            services:
              traefik:
                image: traefik:2.6
                container_name: traefik
                restart: always
                volumes:
                  - ./ssl/acme.json:/etc/traefik/acme.json
                  - /var/run/docker.sock:/var/run/docker.sock
                  - ./conf.d:/etc/traefik/conf.d
                  - ./logs/traefik.log:/etc/traefik/traefik.log
                  - ./logs/access.log:/etc/traefik/access.log
                ports:
                  - 80:80
                  - 443:443
                networks:
                  - traefik
                command:
                  - "--global.sendanonymoususage=false"
                  - "--global.checknewversion=false" 
                  - "--accesslog=true" 
                  - "--api=true"
                  - "--api.insecure=true"
                  - "--api.dashboard=true" 
                  - "--log.level=ERROR"
                  - "--providers.file.directory=/etc/traefik/conf.d/" 
                  - "--providers.file.watch=true" 
                  - "--entrypoints.web.address=:80" 
                  - "--entrypoints.websecure.address=:443"
                  #- "--entrypoints.web.http.redirections.entrypoint.scheme=https" 
                  #- "--entrypoints.web.http.redirections.entrypoint.to=websecure" 
                  - "--certificatesresolvers.letsencrypt-ecdsa.acme.email=xxx@xxx.xx"
                  - "--certificatesresolvers.letsencrypt-ecdsa.acme.caserver=https://acme-v02.api.letsencrypt.org/directory"
                  - "--certificatesresolvers.letsencrypt-ecdsa.acme.storage=/etc/traefik/acme.json"
                  - "--certificatesresolvers.letsencrypt-ecdsa.acme.keytype=EC384"
                  - "--certificatesresolvers.letsencrypt-ecdsa.acme.httpchallenge.entrypoint=web"
                  - "--certificatesresolvers.letsencrypt-ecdsa.acme.tlschallenge=true"
                  - "--certificatesresolvers.letsencrypt-rsa2048.acme.email=xxx@xxx.xx"
                  - "--certificatesresolvers.letsencrypt-rsa2048.acme.caserver=https://acme-v02.api.letsencrypt.org/directory"
                  - "--certificatesresolvers.letsencrypt-rsa2048.acme.storage=/etc/traefik/acme.json"
                  - "--certificatesresolvers.letsencrypt-rsa2048.acme.keytype=RSA2048"
                  - "--certificatesresolvers.letsencrypt-rsa2048.acme.httpchallenge.entrypoint=web"
                  - "--certificatesresolvers.letsencrypt-rsa2048.acme.tlschallenge=true"
            
              whoami:
                image: traefik/whoami
                container_name: whoami
                networks:
                  - traefik
            
            networks:
              traefik:
                external: true

            Impossible d'accéder à la page web : La page n’est pas redirigée correctement.
            Pourtant, dans le dashboard tout semble ok.

            Je suis un peu perdu là... 😩

            [inconnu]
            Salut, le problème est plutôt simple, c'est que tu as une boucle de redirection, tu redirige le router avec la règle whoami.domain.tld vers un service qui pointe sur whoami.domain.tld.

            Ton service devrait être comme ceci :

              services:
                whoami:
                  loadBalancer:
                    servers:
                      - url: "http://whoami"
              Répondre…