Non-existent resolver error with letsencrypt, docker-swarm and traefik v2

I have routing working to my traefik dashboard and portainer services but they still only use self-certified traefik certs.

The docker service logs show the following errors:

msg="the router portainer-secure uses a non-existent resolver: letsencrypt"
msg="the router traefik-secure uses a non-existent resolver: letsencrypt"

I'm passing in service configuration using Ansible docker_swarm_service module, so the labels are in yaml format together with the rest of the service definition and some jinja2 variables are present too:

- name: 'Deploy Traefik'
  docker_swarm_service:
    name: 'traefik'
    image: 'traefik:latest'
    env:
      # These should all be passed in as variables, including keys
      # to support different dns providers
      GANDIV5_API_KEY: "{{ acme_api_key_gandi }}"
      GANDIV5_HTTP_TIMEOUT: '30'
      GANDIV5_POLLING_INTERVAL: '90'
      GANDIV5_PROPAGATION_TIMEOUT: '180'
    labels:
      traefik.enable: 'true'
      traefik.http.routers.traefik.entrypoints: 'http'
      traefik.http.routers.traefik.rule: "Host(`api.{{ traefik_domain }}`)"
      #traefik.http.middlewares.traefik-auth.basicauth.users: "{{ traefik_auth_credentials }}"
      traefik.http.middlewares.https-redirect.redirectscheme.scheme: 'https'
      traefik.http.routers.traefik.middlewares: 'https-redirect'
      traefik.http.routers.traefik-secure.entrypoints: 'https'
      traefik.http.routers.traefik-secure.rule: "Host(`api.{{ traefik_domain }}`)"
      #traefik.http.routers.traefik-secure.middlewares: 'traefik-auth'
      traefik.http.routers.traefik-secure.tls: 'true'
      traefik.http.routers.traefik-secure.tls.certresolver: 'letsencrypt'
      traefik.http.routers.traefik-secure.tls.domains[0].main: "{{ traefik_domain }}"
      traefik.http.routers.traefik-secure.tls.domains[0].sans: "*.{{ traefik_domain }}"
      traefik.http.routers.traefik-secure.service: 'api@internal'
      traefik.http.services.traefik.loadbalancer.server.port: '8080'
    mounts:
      - source: '/var/run/docker.sock'
        target: '/var/run/docker.sock'
        type: 'bind'
        readonly: yes
      - source: '{{ docker_data_dir }}/traefik_data/traefik.toml'
        target: '/traefik.toml'
        type: 'bind'
        readonly: yes
      - source: '{{ docker_data_dir }}/traefik_data/letsencrypt/acme.json'
        target: '/acme.json'
        type: 'bind'
    networks:
      - 'traefik_backend'
    mode: 'global'
    restart_config:
      condition: "{{ restart_condition }}"
    publish:
      - published_port: 80
        target_port: 80
      - published_port: 443
        target_port: 443
      - published_port: 8080
        target_port: 8080
    placement:
      constraints:
        - 'node.role == manager'
    user: null

The traefik.toml Ansible copies to the server is:

[global]
  sendAnonymousUsage = true

[api]
  dashboard = true
  debug = true
  insecure = false

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

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

[certificatesResolvers]
  [certificatesResolvers.letsencrypt]
    [certificatesResolvers.letsencrypt.acme]
      email = "adrian@perlucida.com"
      storage = "acme.json"
      # Uncomment to use Let's Encrypt's staging server, leave commented for prod
      caServer = "https://acme-staging-v02.api.letsencrypt.org/directory"
      [certificatesResolvers.letsencrypt.acme.dnsChallenge]
        provider= "gandiv5"

        # By default, the provider will verify the TXT DNS challenge record before letting ACME verify.
        # If delayBeforeCheck is greater than zero, this check is delayed for the configured duration in seconds.
        delayBeforeCheck = 0

        # Use following DNS servers to resolve the FQDN authority.
        #
        # Optional
        # Default: empty
        #
        resolvers = ["1.1.1.1:53", "8.8.8.8:53"]

I feel like this must be some simple syntax error but having read the docs repeatedly and looked at several examples I just cant see anything wrong.

Think I'll try ansible with

ANSIBLE_KEEP_REMOTE_FILES=1

later see if I can see any errors in the processed service config.

Please don't use traefik:latest: friends don't let friends use latest

I recommend to use an explicit version like v2.0.1 or if you cannot you can use v2.0

Looks like changing the tag to :v2.0 has removed that error. Thanks @ldez

Still don't have working letsencrypt certs from dnschallenge, but now I know that error is nothing to do with it :slight_smile:

I'll keep digging.