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.