Let’s Encrypt

Automatic HTTPS

You can configure Traefik to use an ACME provider (like Let’s Encrypt) for automatic certificate generation.

Let’s Encrypt and Rate Limiting

Note that Let’s Encrypt API has rate limiting. These last up to one week, and can not be overridden.

When running Traefik in a container this file should be persisted across restarts. If Traefik requests new certificates each time it starts up, a crash-looping container can quickly reach Let’s Encrypt’s ratelimits. To configure where certificates are stored, please take a look at the storage configuration.

Use Let’s Encrypt staging server with the caServer configuration option when experimenting to avoid hitting this limit too fast.

Certificate Resolvers

Traefik requires you to define “Certificate Resolvers” in the static configuration, which are responsible for retrieving certificates from an ACME server.

Then, each “router” is configured to enable TLS, and is associated to a certificate resolver through the tls.certresolver configuration option.

Certificates are requested for domain names retrieved from the router’s dynamic configuration.

You can read more about this retrieval mechanism in the following section: ACME Domain Definition.

Defining an ACME challenge type is a requirement for a certificate resolver to be functional.

Defining a certificate resolver does not result in all routers automatically using it. Each router that is supposed to use the resolver must reference it.

Configuration Reference

There are many available options for ACME. For a quick glance at what’s possible, browse the configuration reference:

File (YAML)

  1. certificatesResolvers:
  2. myresolver:
  3. # Enable ACME (Let's Encrypt): automatic SSL.
  4. acme:
  5. # Email address used for registration.
  6. #
  7. # Required
  8. #
  9. email: "[email protected]"
  10. # File or key used for certificates storage.
  11. #
  12. # Required
  13. #
  14. storage: "acme.json"
  15. # CA server to use.
  16. # Uncomment the line to use Let's Encrypt's staging server,
  17. # leave commented to go to prod.
  18. #
  19. # Optional
  20. # Default: "https://acme-v02.api.letsencrypt.org/directory"
  21. #
  22. # caServer: "https://acme-staging-v02.api.letsencrypt.org/directory"
  23. # The certificates' duration in hours.
  24. # It defaults to 2160 (90 days) to follow Let's Encrypt certificates' duration.
  25. #
  26. # Optional
  27. # Default: 2160
  28. #
  29. # certificatesDuration: 2160
  30. # Preferred chain to use.
  31. #
  32. # If the CA offers multiple certificate chains, prefer the chain with an issuer matching this Subject Common Name.
  33. # If no match, the default offered chain will be used.
  34. #
  35. # Optional
  36. # Default: ""
  37. #
  38. # preferredChain: 'ISRG Root X1'
  39. # KeyType to use.
  40. #
  41. # Optional
  42. # Default: "RSA4096"
  43. #
  44. # Available values : "EC256", "EC384", "RSA2048", "RSA4096", "RSA8192"
  45. #
  46. # keyType: RSA4096
  47. # Use a TLS-ALPN-01 ACME challenge.
  48. #
  49. # Optional (but recommended)
  50. #
  51. tlsChallenge:
  52. # Use a HTTP-01 ACME challenge.
  53. #
  54. # Optional
  55. #
  56. # httpChallenge:
  57. # EntryPoint to use for the HTTP-01 challenges.
  58. #
  59. # Required
  60. #
  61. # entryPoint: web
  62. # Use a DNS-01 ACME challenge rather than HTTP-01 challenge.
  63. # Note: mandatory for wildcard certificate generation.
  64. #
  65. # Optional
  66. #
  67. # dnsChallenge:
  68. # DNS provider used.
  69. #
  70. # Required
  71. #
  72. # provider: digitalocean
  73. # By default, the provider will verify the TXT DNS challenge record before letting ACME verify.
  74. # If delayBeforeCheck is greater than zero, this check is delayed for the configured duration in seconds.
  75. # Useful if internal networks block external DNS queries.
  76. #
  77. # Optional
  78. # Default: 0
  79. #
  80. # delayBeforeCheck: 0
  81. # Use following DNS servers to resolve the FQDN authority.
  82. #
  83. # Optional
  84. # Default: empty
  85. #
  86. # resolvers
  87. # - "1.1.1.1:53"
  88. # - "8.8.8.8:53"
  89. # Disable the DNS propagation checks before notifying ACME that the DNS challenge is ready.
  90. #
  91. # NOT RECOMMENDED:
  92. # Increase the risk of reaching Let's Encrypt's rate limits.
  93. #
  94. # Optional
  95. # Default: false
  96. #
  97. # disablePropagationCheck: true

File (TOML)

  1. # Enable ACME (Let's Encrypt): automatic SSL.
  2. [certificatesResolvers.myresolver.acme]
  3. # Email address used for registration.
  4. #
  5. # Required
  6. #
  7. email = "[email protected]"
  8. # File or key used for certificates storage.
  9. #
  10. # Required
  11. #
  12. storage = "acme.json"
  13. # CA server to use.
  14. # Uncomment the line to use Let's Encrypt's staging server,
  15. # leave commented to go to prod.
  16. #
  17. # Optional
  18. # Default: "https://acme-v02.api.letsencrypt.org/directory"
  19. #
  20. # caServer = "https://acme-staging-v02.api.letsencrypt.org/directory"
  21. # The certificates' duration in hours.
  22. # It defaults to 2160 (90 days) to follow Let's Encrypt certificates' duration.
  23. #
  24. # Optional
  25. # Default: 2160
  26. #
  27. # certificatesDuration=2160
  28. # Preferred chain to use.
  29. #
  30. # If the CA offers multiple certificate chains, prefer the chain with an issuer matching this Subject Common Name.
  31. # If no match, the default offered chain will be used.
  32. #
  33. # Optional
  34. # Default: ""
  35. #
  36. # preferredChain = "ISRG Root X1"
  37. # KeyType to use.
  38. #
  39. # Optional
  40. # Default: "RSA4096"
  41. #
  42. # Available values : "EC256", "EC384", "RSA2048", "RSA4096", "RSA8192"
  43. #
  44. # keyType = "RSA4096"
  45. # Use a TLS-ALPN-01 ACME challenge.
  46. #
  47. # Optional (but recommended)
  48. #
  49. [certificatesResolvers.myresolver.acme.tlsChallenge]
  50. # Use a HTTP-01 ACME challenge.
  51. #
  52. # Optional
  53. #
  54. # [certificatesResolvers.myresolver.acme.httpChallenge]
  55. # EntryPoint to use for the HTTP-01 challenges.
  56. #
  57. # Required
  58. #
  59. # entryPoint = "web"
  60. # Use a DNS-01 ACME challenge rather than HTTP-01 challenge.
  61. # Note: mandatory for wildcard certificate generation.
  62. #
  63. # Optional
  64. #
  65. # [certificatesResolvers.myresolver.acme.dnsChallenge]
  66. # DNS provider used.
  67. #
  68. # Required
  69. #
  70. # provider = "digitalocean"
  71. # By default, the provider will verify the TXT DNS challenge record before letting ACME verify.
  72. # If delayBeforeCheck is greater than zero, this check is delayed for the configured duration in seconds.
  73. # Useful if internal networks block external DNS queries.
  74. #
  75. # Optional
  76. # Default: 0
  77. #
  78. # delayBeforeCheck = 0
  79. # Use following DNS servers to resolve the FQDN authority.
  80. #
  81. # Optional
  82. # Default: empty
  83. #
  84. # resolvers = ["1.1.1.1:53", "8.8.8.8:53"]
  85. # Disable the DNS propagation checks before notifying ACME that the DNS challenge is ready.
  86. #
  87. # NOT RECOMMENDED:
  88. # Increase the risk of reaching Let's Encrypt's rate limits.
  89. #
  90. # Optional
  91. # Default: false
  92. #
  93. # disablePropagationCheck = true

CLI

  1. # Enable ACME (Let's Encrypt): automatic SSL.
  2. # Email address used for registration.
  3. #
  4. # Required
  5. #
  6. [email protected]
  7. # File or key used for certificates storage.
  8. #
  9. # Required
  10. #
  11. --certificatesresolvers.myresolver.acme.storage=acme.json
  12. # CA server to use.
  13. # Uncomment the line to use Let's Encrypt's staging server,
  14. # leave commented to go to prod.
  15. #
  16. # Optional
  17. # Default: "https://acme-v02.api.letsencrypt.org/directory"
  18. #
  19. --certificatesresolvers.myresolver.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory
  20. # The certificates' duration in hours.
  21. # It defaults to 2160 (90 days) to follow Let's Encrypt certificates' duration.
  22. #
  23. # Optional
  24. # Default: 2160
  25. #
  26. --certificatesresolvers.myresolver.acme.certificatesDuration=2160
  27. # Preferred chain to use.
  28. #
  29. # If the CA offers multiple certificate chains, prefer the chain with an issuer matching this Subject Common Name.
  30. # If no match, the default offered chain will be used.
  31. #
  32. # Optional
  33. # Default: ""
  34. #
  35. --certificatesresolvers.myresolver.acme.preferredchain="ISRG Root X1"
  36. # KeyType to use.
  37. #
  38. # Optional
  39. # Default: "RSA4096"
  40. #
  41. # Available values : "EC256", "EC384", "RSA2048", "RSA4096", "RSA8192"
  42. #
  43. --certificatesresolvers.myresolver.acme.keytype=RSA4096
  44. # Use a TLS-ALPN-01 ACME challenge.
  45. #
  46. # Optional (but recommended)
  47. #
  48. --certificatesresolvers.myresolver.acme.tlschallenge=true
  49. # Use a HTTP-01 ACME challenge.
  50. #
  51. # Optional
  52. #
  53. --certificatesresolvers.myresolver.acme.httpchallenge=true
  54. # EntryPoint to use for the HTTP-01 challenges.
  55. #
  56. # Required
  57. #
  58. --certificatesresolvers.myresolver.acme.httpchallenge.entrypoint=web
  59. # Use a DNS-01 ACME challenge rather than HTTP-01 challenge.
  60. # Note: mandatory for wildcard certificate generation.
  61. #
  62. # Optional
  63. #
  64. --certificatesresolvers.myresolver.acme.dnschallenge=true
  65. # DNS provider used.
  66. #
  67. # Required
  68. #
  69. --certificatesresolvers.myresolver.acme.dnschallenge.provider=digitalocean
  70. # By default, the provider will verify the TXT DNS challenge record before letting ACME verify.
  71. # If delayBeforeCheck is greater than zero, this check is delayed for the configured duration in seconds.
  72. # Useful if internal networks block external DNS queries.
  73. #
  74. # Optional
  75. # Default: 0
  76. #
  77. --certificatesresolvers.myresolver.acme.dnschallenge.delaybeforecheck=0
  78. # Use following DNS servers to resolve the FQDN authority.
  79. #
  80. # Optional
  81. # Default: empty
  82. #
  83. --certificatesresolvers.myresolver.acme.dnschallenge.resolvers=1.1.1.1:53,8.8.8.8:53
  84. # Disable the DNS propagation checks before notifying ACME that the DNS challenge is ready.
  85. #
  86. # NOT RECOMMENDED:
  87. # Increase the risk of reaching Let's Encrypt's rate limits.
  88. #
  89. # Optional
  90. # Default: false
  91. #
  92. --certificatesresolvers.myresolver.acme.dnschallenge.disablepropagationcheck=true

Domain Definition

Certificate resolvers request certificates for a set of the domain names inferred from routers, with the following logic:

  • If the router has a tls.domains option set, then the certificate resolver uses the main (and optionally sans) option of tls.domains to know the domain names for this router.

  • If no tls.domains option is set, then the certificate resolver uses the router’s rule, by checking the Host() matchers. Please note that multiple Host() matchers can be used) for specifying multiple domain names for this router.

Please note that:

Please check the configuration examples below for more details.

Configuration Examples

Enabling ACME

File (YAML)

  1. entryPoints:
  2. web:
  3. address: ":80"
  4. websecure:
  5. address: ":443"
  6. certificatesResolvers:
  7. myresolver:
  8. acme:
  9. email: [email protected]
  10. storage: acme.json
  11. httpChallenge:
  12. # used during the challenge
  13. entryPoint: web

File (TOML)

  1. [entryPoints]
  2. [entryPoints.web]
  3. address = ":80"
  4. [entryPoints.websecure]
  5. address = ":443"
  6. [certificatesResolvers.myresolver.acme]
  7. email = "[email protected]"
  8. storage = "acme.json"
  9. [certificatesResolvers.myresolver.acme.httpChallenge]
  10. # used during the challenge
  11. entryPoint = "web"

CLI

  1. --entrypoints.web.address=:80
  2. --entrypoints.websecure.address=:443
  3. # ...
  4. --certificatesresolvers.myresolver.acme.email=your-email@example.com
  5. --certificatesresolvers.myresolver.acme.storage=acme.json
  6. # used during the challenge
  7. --certificatesresolvers.myresolver.acme.httpchallenge.entrypoint=web

Defining a certificate resolver does not result in all routers automatically using it. Each router that is supposed to use the resolver must reference it.

Single Domain from Router’s Rule Example

  • A certificate for the domain example.com is requested:

Docker

  1. ## Dynamic configuration
  2. labels:
  3. - traefik.http.routers.blog.rule=Host(`example.com`) && Path(`/blog`)
  4. - traefik.http.routers.blog.tls=true
  5. - traefik.http.routers.blog.tls.certresolver=myresolver

Docker (Swarm)

  1. ## Dynamic configuration
  2. deploy:
  3. labels:
  4. - traefik.http.routers.blog.rule=Host(`example.com`) && Path(`/blog`)
  5. - traefik.http.routers.blog.tls=true
  6. - traefik.http.routers.blog.tls.certresolver=myresolver
  7. - traefik.http.services.blog-svc.loadbalancer.server.port=8080"

Kubernetes

  1. apiVersion: traefik.io/v1alpha1
  2. kind: IngressRoute
  3. metadata:
  4. name: blogtls
  5. spec:
  6. entryPoints:
  7. - websecure
  8. routes:
  9. - match: Host(`example.com`) && Path(`/blog`)
  10. kind: Rule
  11. services:
  12. - name: blog
  13. port: 8080
  14. tls:
  15. certResolver: myresolver

Marathon

  1. labels: {
  2. "traefik.http.routers.blog.rule": "Host(`example.com`) && Path(`/blog`)",
  3. "traefik.http.routers.blog.tls": "true",
  4. "traefik.http.routers.blog.tls.certresolver": "myresolver",
  5. "traefik.http.services.blog-svc.loadbalancer.server.port": "8080"
  6. }

Rancher

  1. ## Dynamic configuration
  2. labels:
  3. - traefik.http.routers.blog.rule=Host(`example.com`) && Path(`/blog`)
  4. - traefik.http.routers.blog.tls=true
  5. - traefik.http.routers.blog.tls.certresolver=myresolver

File (YAML)

  1. ## Dynamic configuration
  2. http:
  3. routers:
  4. blog:
  5. rule: "Host(`example.com`) && Path(`/blog`)"
  6. tls:
  7. certResolver: myresolver

File (TOML)

  1. ## Dynamic configuration
  2. [http.routers]
  3. [http.routers.blog]
  4. rule = "Host(`example.com`) && Path(`/blog`)"
  5. [http.routers.blog.tls]
  6. certResolver = "myresolver"

Multiple Domains from Router’s Rule Example

  • A certificate for the domains example.com (main) and blog.example.org is requested:

Docker

  1. ## Dynamic configuration
  2. labels:
  3. - traefik.http.routers.blog.rule=(Host(`example.com`) && Path(`/blog`)) || Host(`blog.example.org`)
  4. - traefik.http.routers.blog.tls=true
  5. - traefik.http.routers.blog.tls.certresolver=myresolver

Docker (Swarm)

  1. ## Dynamic configuration
  2. deploy:
  3. labels:
  4. - traefik.http.routers.blog.rule=(Host(`example.com`) && Path(`/blog`)) || Host(`blog.example.org`)
  5. - traefik.http.routers.blog.tls=true
  6. - traefik.http.routers.blog.tls.certresolver=myresolver
  7. - traefik.http.services.blog-svc.loadbalancer.server.port=8080"

Kubernetes

  1. apiVersion: traefik.io/v1alpha1
  2. kind: IngressRoute
  3. metadata:
  4. name: blogtls
  5. spec:
  6. entryPoints:
  7. - websecure
  8. routes:
  9. - match: (Host(`example.com`) && Path(`/blog`)) || Host(`blog.example.org`)
  10. kind: Rule
  11. services:
  12. - name: blog
  13. port: 8080
  14. tls:
  15. certResolver: myresolver

Marathon

  1. labels: {
  2. "traefik.http.routers.blog.rule": "(Host(`example.com`) && Path(`/blog`)) || Host(`blog.example.org`)",
  3. "traefik.http.routers.blog.tls": "true",
  4. "traefik.http.routers.blog.tls.certresolver": "myresolver",
  5. "traefik.http.services.blog-svc.loadbalancer.server.port": "8080"
  6. }

Rancher

  1. ## Dynamic configuration
  2. labels:
  3. - traefik.http.routers.blog.rule=(Host(`example.com`) && Path(`/blog`)) || Host(`blog.example.org`)
  4. - traefik.http.routers.blog.tls=true
  5. - traefik.http.routers.blog.tls.certresolver=myresolver

File (YAML)

  1. ## Dynamic configuration
  2. http:
  3. routers:
  4. blog:
  5. rule: "(Host(`example.com`) && Path(`/blog`)) || Host(`blog.example.org`)"
  6. tls:
  7. certResolver: myresolver

File (TOML)

  1. ## Dynamic configuration
  2. [http.routers]
  3. [http.routers.blog]
  4. rule = "(Host(`example.com`) && Path(`/blog`)) || Host(`blog.example.org`)"
  5. [http.routers.blog.tls]
  6. certResolver = "myresolver"

Multiple Domains from Router’s tls.domain Example

  • A certificate for the domains example.com (main) and *.example.org (SAN) is requested:

Docker

  1. ## Dynamic configuration
  2. labels:
  3. - traefik.http.routers.blog.rule=Host(`example.com`) && Path(`/blog`)
  4. - traefik.http.routers.blog.tls=true
  5. - traefik.http.routers.blog.tls.certresolver=myresolver
  6. - traefik.http.routers.blog.tls.domains[0].main=example.org
  7. - traefik.http.routers.blog.tls.domains[0].sans=*.example.org

Docker (Swarm)

  1. ## Dynamic configuration
  2. deploy:
  3. labels:
  4. - traefik.http.routers.blog.rule=Host(`example.com`) && Path(`/blog`)
  5. - traefik.http.services.blog-svc.loadbalancer.server.port=8080"
  6. - traefik.http.routers.blog.tls=true
  7. - traefik.http.routers.blog.tls.certresolver=myresolver
  8. - traefik.http.routers.blog.tls.domains[0].main=example.org
  9. - traefik.http.routers.blog.tls.domains[0].sans=*.example.org

Kubernetes

  1. apiVersion: traefik.io/v1alpha1
  2. kind: IngressRoute
  3. metadata:
  4. name: blogtls
  5. spec:
  6. entryPoints:
  7. - websecure
  8. routes:
  9. - match: Host(`example.com`) && Path(`/blog`)
  10. kind: Rule
  11. services:
  12. - name: blog
  13. port: 8080
  14. tls:
  15. certResolver: myresolver
  16. domains:
  17. - main: example.org
  18. sans:
  19. - '*.example.org'

Marathon

  1. labels: {
  2. "traefik.http.routers.blog.rule": "Host(`example.com`) && Path(`/blog`)",
  3. "traefik.http.routers.blog.tls": "true",
  4. "traefik.http.routers.blog.tls.certresolver": "myresolver",
  5. "traefik.http.routers.blog.tls.domains[0].main": "example.com",
  6. "traefik.http.routers.blog.tls.domains[0].sans": "*.example.com",
  7. "traefik.http.services.blog-svc.loadbalancer.server.port": "8080"
  8. }

Rancher

  1. ## Dynamic configuration
  2. labels:
  3. - traefik.http.routers.blog.rule=Host(`example.com`) && Path(`/blog`)
  4. - traefik.http.routers.blog.tls=true
  5. - traefik.http.routers.blog.tls.certresolver=myresolver
  6. - traefik.http.routers.blog.tls.domains[0].main=example.org
  7. - traefik.http.routers.blog.tls.domains[0].sans=*.example.org

File (YAML)

  1. ## Dynamic configuration
  2. http:
  3. routers:
  4. blog:
  5. rule: "Host(`example.com`) && Path(`/blog`)"
  6. tls:
  7. certResolver: myresolver
  8. domains:
  9. - main: "example.org"
  10. sans:
  11. - "*.example.org"

File (TOML)

  1. ## Dynamic configuration
  2. [http.routers]
  3. [http.routers.blog]
  4. rule = "Host(`example.com`) && Path(`/blog`)"
  5. [http.routers.blog.tls]
  6. certResolver = "myresolver" # From static configuration
  7. [[http.routers.blog.tls.domains]]
  8. main = "example.org"
  9. sans = ["*.example.org"]

Automatic Renewals

Traefik automatically tracks the expiry date of ACME certificates it generates.

By default, Traefik manages 90 days certificates, and starts to renew certificates 30 days before their expiry.

When using a certificate resolver that issues certificates with custom durations, one can configure the certificates’ duration with the certificatesDuration option.

Certificates that are no longer used may still be renewed, as Traefik does not currently check if the certificate is being used before renewing.

Using LetsEncrypt with Kubernetes

When using LetsEncrypt with kubernetes, there are some known caveats with both the ingress and crd providers.

If you intend to run multiple instances of Traefik with LetsEncrypt, please ensure you read the sections on those provider pages.

The Different ACME Challenges

Defining one ACME challenge is a requirement for a certificate resolver to be functional.

Defining a certificate resolver does not result in all routers automatically using it. Each router that is supposed to use the resolver must reference it.

tlsChallenge

Use the TLS-ALPN-01 challenge to generate and renew ACME certificates by provisioning a TLS certificate.

As described on the Let’s Encrypt community forum, when using the TLS-ALPN-01 challenge, Traefik must be reachable by Let’s Encrypt through port 443.

Configuring the tlsChallenge

File (YAML)

  1. certificatesResolvers:
  2. myresolver:
  3. acme:
  4. # ...
  5. tlsChallenge: {}

File (TOML)

  1. [certificatesResolvers.myresolver.acme]
  2. # ...
  3. [certificatesResolvers.myresolver.acme.tlsChallenge]

CLI

  1. # ...
  2. --certificatesresolvers.myresolver.acme.tlschallenge=true

httpChallenge

Use the HTTP-01 challenge to generate and renew ACME certificates by provisioning an HTTP resource under a well-known URI.

As described on the Let’s Encrypt community forum, when using the HTTP-01 challenge, certificatesresolvers.myresolver.acme.httpchallenge.entrypoint must be reachable by Let’s Encrypt through port 80.

Using an EntryPoint Called web for the httpChallenge

File (YAML)

  1. entryPoints:
  2. web:
  3. address: ":80"
  4. websecure:
  5. address: ":443"
  6. certificatesResolvers:
  7. myresolver:
  8. acme:
  9. # ...
  10. httpChallenge:
  11. entryPoint: web

File (TOML)

  1. [entryPoints]
  2. [entryPoints.web]
  3. address = ":80"
  4. [entryPoints.websecure]
  5. address = ":443"
  6. [certificatesResolvers.myresolver.acme]
  7. # ...
  8. [certificatesResolvers.myresolver.acme.httpChallenge]
  9. entryPoint = "web"

CLI

  1. --entrypoints.web.address=:80
  2. --entrypoints.websecure.address=:443
  3. # ...
  4. --certificatesresolvers.myresolver.acme.httpchallenge.entrypoint=web

Redirection is fully compatible with the HTTP-01 challenge.

dnsChallenge

Use the DNS-01 challenge to generate and renew ACME certificates by provisioning a DNS record.

Configuring a dnsChallenge with the DigitalOcean Provider

File (YAML)

  1. certificatesResolvers:
  2. myresolver:
  3. acme:
  4. # ...
  5. dnsChallenge:
  6. provider: digitalocean
  7. delayBeforeCheck: 0
  8. # ...

File (TOML)

  1. [certificatesResolvers.myresolver.acme]
  2. # ...
  3. [certificatesResolvers.myresolver.acme.dnsChallenge]
  4. provider = "digitalocean"
  5. delayBeforeCheck = 0
  6. # ...

CLI

  1. # ...
  2. --certificatesresolvers.myresolver.acme.dnschallenge.provider=digitalocean
  3. --certificatesresolvers.myresolver.acme.dnschallenge.delaybeforecheck=0
  4. # ...

CNAME support

CNAME are supported (and sometimes even encouraged), but there are a few cases where they can be problematic.

If needed, CNAME support can be disabled with the following environment variable:

  1. LEGO_DISABLE_CNAME_SUPPORT=true

Multiple DNS Challenge provider

Multiple DNS challenge provider are not supported with Traefik, but you can use CNAME to handle that. For example, if you have example.org (account foo) and example.com (account bar) you can create a CNAME on example.org called _acme-challenge.example.org pointing to challenge.example.com. This way, you can obtain certificates for example.com with the foo account.

Important

A provider is mandatory.

providers

Here is a list of supported providers, that can automate the DNS verification, along with the required environment variables and their wildcard & root domain support. Do not hesitate to complete it.

Many lego environment variables can be overridden by their respective _FILE counterpart, which should have a filepath to a file that contains the secret as its value. For example, CF_API_EMAIL_FILE=/run/secrets/traefik_cf-api-email could be used to provide a Cloudflare API email address as a Docker secret named traefik_cf-api-email.

For complete details, refer to your provider’s Additional configuration link.

Provider NameProvider CodeEnvironment Variables
ACME DNSacme-dnsACME_DNS_API_BASE, ACME_DNS_STORAGE_PATHAdditional configuration
Alibaba CloudalidnsALICLOUD_ACCESS_KEY, ALICLOUD_SECRET_KEY, ALICLOUD_REGION_IDAdditional configuration
all-inklallinklALL_INKL_LOGIN, ALL_INKL_PASSWORDAdditional configuration
ArvanCloudarvancloudARVANCLOUD_API_KEYAdditional configuration
AuroradnsauroradnsAURORA_USER_ID, AURORA_KEY, AURORA_ENDPOINTAdditional configuration
AutodnsautodnsAUTODNS_API_USER, AUTODNS_API_PASSWORDAdditional configuration
Azure (DEPRECATED)azureAZURE_CLIENT_ID, AZURE_CLIENT_SECRET, AZURE_SUBSCRIPTION_ID, AZURE_TENANT_ID, AZURE_RESOURCE_GROUP, [AZURE_METADATA_ENDPOINT]Additional configuration
AzureDNSazurednsAZURE_CLIENT_ID, AZURE_CLIENT_SECRET, AZURE_TENANT_ID, AZURE_SUBSCRIPTION_ID, AZURE_RESOURCE_GROUP, [AZURE_ENVIRONMENT], [AZURE_PRIVATE_ZONE], [AZURE_ZONE_NAME]Additional configuration
BindmanbindmanBINDMAN_MANAGER_ADDRESSAdditional configuration
Blue CatbluecatBLUECAT_SERVER_URL, BLUECAT_USER_NAME, BLUECAT_PASSWORD, BLUECAT_CONFIG_NAME, BLUECAT_DNS_VIEWAdditional configuration
BranditbranditBRANDIT_API_USERNAME, BRANDIT_API_KEYAdditional configuration
BunnybunnyBUNNY_API_KEYAdditional configuration
CheckdomaincheckdomainCHECKDOMAIN_TOKEN,Additional configuration
CivocivoCIVO_TOKENAdditional configuration
Cloud.rucloudruCLOUDRU_SERVICE_INSTANCE_ID, CLOUDRU_KEY_ID, CLOUDRU_SECRETAdditional configuration
CloudDNSclouddnsCLOUDDNS_CLIENT_ID, CLOUDDNS_EMAIL, CLOUDDNS_PASSWORDAdditional configuration
CloudflarecloudflareCF_API_EMAIL, CF_API_KEY 5 or CF_DNS_API_TOKEN, [CF_ZONE_API_TOKEN]Additional configuration
ClouDNScloudnsCLOUDNS_AUTH_ID, CLOUDNS_AUTH_PASSWORDAdditional configuration
CloudXNScloudxnsCLOUDXNS_API_KEY, CLOUDXNS_SECRET_KEYAdditional configuration
ConoHaconohaCONOHA_TENANT_ID, CONOHA_API_USERNAME, CONOHA_API_PASSWORDAdditional configuration
ConstellixconstellixCONSTELLIX_API_KEY, CONSTELLIX_SECRET_KEYAdditional configuration
Derak CloudderakDERAK_API_KEYAdditional configuration
deSECdesecDESEC_TOKENAdditional configuration
DigitalOceandigitaloceanDO_AUTH_TOKENAdditional configuration
DNS Made EasydnsmadeeasyDNSMADEEASY_API_KEY, DNSMADEEASY_API_SECRET, DNSMADEEASY_SANDBOXAdditional configuration
dnsHome.dednsHomedeDNSHOMEDE_CREDENTIALSAdditional configuration
DNSimplednsimpleDNSIMPLE_OAUTH_TOKEN, DNSIMPLE_BASE_URLAdditional configuration
DNSPoddnspodDNSPOD_API_KEYAdditional configuration
Domain Offensive (do.de)dodeDODE_TOKENAdditional configuration
DomeneshopdomeneshopDOMENESHOP_API_TOKEN, DOMENESHOP_API_SECRETAdditional configuration
DreamHostdreamhostDREAMHOST_API_KEYAdditional configuration
Duck DNSduckdnsDUCKDNS_TOKENAdditional configuration
DyndynDYN_CUSTOMER_NAME, DYN_USER_NAME, DYN_PASSWORDAdditional configuration
DynudynuDYNU_API_KEYAdditional configuration
EasyDNSeasydnsEASYDNS_TOKEN, EASYDNS_KEYAdditional configuration
EdgeDNSedgednsAKAMAI_CLIENT_TOKEN, AKAMAI_CLIENT_SECRET, AKAMAI_ACCESS_TOKENAdditional configuration
Efficient IPefficientipEFFICIENTIP_USERNAME, EFFICIENTIP_PASSWORD, EFFICIENTIP_HOSTNAME, EFFICIENTIP_DNS_NAMEAdditional configuration
EpikepikEPIK_SIGNATUREAdditional configuration
ExoscaleexoscaleEXOSCALE_API_KEY, EXOSCALE_API_SECRET, EXOSCALE_ENDPOINTAdditional configuration
Fast DNSfastdnsAKAMAI_CLIENT_TOKEN, AKAMAI_CLIENT_SECRET, AKAMAI_ACCESS_TOKENAdditional configuration
Freemyip.comfreemyipFREEMYIP_TOKENAdditional configuration
G-CoregcoreGCORE_PERMANENT_API_TOKENAdditional configuration
Gandi v5gandiv5GANDIV5_API_KEYAdditional configuration
GandigandiGANDI_API_KEYAdditional configuration
GlesysglesysGLESYS_API_USER, GLESYS_API_KEY, GLESYS_DOMAINAdditional configuration
GoDaddygodaddyGODADDY_API_KEY, GODADDY_API_SECRETAdditional configuration
Google Cloud DNSgcloudGCE_PROJECT, Application Default Credentials 2 3, [GCE_SERVICE_ACCOUNT_FILE]Additional configuration
Google DomainsgoogledomainsGOOGLE_DOMAINS_ACCESS_TOKENAdditional configuration
HetznerhetznerHETZNER_API_KEYAdditional configuration
hosting.dehostingdeHOSTINGDE_API_KEY, HOSTINGDE_ZONE_NAMEAdditional configuration
HosttechhosttechHOSTTECH_API_KEYAdditional configuration
http.nethttpnetHTTPNET_API_KEYAdditional configuration
Hurricane ElectrichurricaneHURRICANE_TOKENS 6Additional configuration
HyperOnehyperoneHYPERONE_PASSPORT_LOCATION, HYPERONE_LOCATION_IDAdditional configuration
IBM Cloud (SoftLayer)ibmcloudSOFTLAYER_USERNAME, SOFTLAYER_API_KEYAdditional configuration
IIJ DNS Platform ServiceiijdpfIIJ_DPF_API_TOKEN , IIJ_DPF_DPM_SERVICE_CODEAdditional configuration
IIJiijIIJ_API_ACCESS_KEY, IIJ_API_SECRET_KEY, IIJ_DO_SERVICE_CODEAdditional configuration
InfobloxinfobloxINFOBLOX_USERNAME, INFOBLOX_PASSWORD, INFOBLOX_HOSTAdditional configuration
InfomaniakinfomaniakINFOMANIAK_ACCESS_TOKENAdditional configuration
Internet.bsinternetbsINTERNET_BS_API_KEY, INTERNET_BS_PASSWORDAdditional configuration
INWXinwxINWX_USERNAME, INWX_PASSWORDAdditional configuration
ionosionosIONOS_API_KEYAdditional configuration
IPv64ipv64IPV64_API_KEYAdditional configuration
iwantmynameiwantmynameIWANTMYNAME_USERNAME , IWANTMYNAME_PASSWORDAdditional configuration
Joker.comjokerJOKER_API_MODE with JOKER_API_KEY or JOKER_USERNAME, JOKER_PASSWORDAdditional configuration
LiaraliaraLIARA_API_KEYAdditional configuration
LightsaillightsailAWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, DNS_ZONEAdditional configuration
Linode v4linodeLINODE_TOKENAdditional configuration
Liquid WebliquidwebLIQUID_WEB_PASSWORD, LIQUID_WEB_USERNAME, LIQUID_WEB_ZONEAdditional configuration
LoopialoopiaLOOPIA_API_PASSWORD, LOOPIA_API_USERAdditional configuration
LuaDNSluadnsLUADNS_API_USERNAME, LUADNS_API_TOKENAdditional configuration
MetanamemetanameMETANAME_ACCOUNT_REFERENCE, METANAME_API_KEYAdditional configuration
MyDNS.jpmydnsjpMYDNSJP_MASTER_ID, MYDNSJP_PASSWORDAdditional configuration
Mythic BeastsmythicbeastsMYTHICBEASTS_USER_NAME, MYTHICBEASTS_PASSWORDAdditional configuration
name.comnamedotcomNAMECOM_USERNAME, NAMECOM_API_TOKEN, NAMECOM_SERVERAdditional configuration
NamecheapnamecheapNAMECHEAP_API_USER, NAMECHEAP_API_KEYAdditional configuration
NamesilonamesiloNAMESILO_API_KEYAdditional configuration
NearlyFreeSpeech.NETnearlyfreespeechNEARLYFREESPEECH_API_KEY, NEARLYFREESPEECH_LOGINAdditional configuration
NetcupnetcupNETCUP_CUSTOMER_NUMBER, NETCUP_API_KEY, NETCUP_API_PASSWORDAdditional configuration
NetlifynetlifyNETLIFY_TOKENAdditional configuration
NicmanagernicmanagerNICMANAGER_API_EMAIL, NICMANAGER_API_PASSWORDAdditional configuration
NIFCloudnifcloudNIFCLOUD_ACCESS_KEY_ID, NIFCLOUD_SECRET_ACCESS_KEYAdditional configuration
NjallanjallaNJALLA_TOKENAdditional configuration
NodionnodionNODION_API_TOKENAdditional configuration
NS1ns1NS1_API_KEYAdditional configuration
Open Telekom CloudotcOTC_DOMAIN_NAME, OTC_USER_NAME, OTC_PASSWORD, OTC_PROJECT_NAME, OTC_IDENTITY_ENDPOINTAdditional configuration
Openstack DesignatedesignateOS_AUTH_URL, OS_USERNAME, OS_PASSWORD, OS_TENANT_NAME, OS_REGION_NAMEAdditional configuration
Oracle CloudoraclecloudOCI_COMPARTMENT_OCID, OCI_PRIVKEY_FILE, OCI_PRIVKEY_PASS, OCI_PUBKEY_FINGERPRINT, OCI_REGION, OCI_TENANCY_OCID, OCI_USER_OCIDAdditional configuration
OVHovhOVH_ENDPOINT, OVH_APPLICATION_KEY, OVH_APPLICATION_SECRET, OVH_CONSUMER_KEYAdditional configuration
PleskpleskPLESK_SERVER_BASE_URL, PLESK_USERNAME, PLESK_PASSWORDAdditional configuration
PorkbunporkbunPORKBUN_SECRET_API_KEY, PORKBUN_API_KEYAdditional configuration
PowerDNSpdnsPDNS_API_KEY, PDNS_API_URLAdditional configuration
RackspacerackspaceRACKSPACE_USER, RACKSPACE_API_KEYAdditional configuration
RcodeZerorcodezeroRCODEZERO_API_TOKENAdditional configuration
reg.ruregruREGRU_USERNAME, REGRU_PASSWORDAdditional configuration
RFC2136rfc2136RFC2136_TSIG_KEY, RFC2136_TSIG_SECRET, RFC2136_TSIG_ALGORITHM, RFC2136_NAMESERVERAdditional configuration
RimuHostingrimuhostingRIMUHOSTING_API_KEYAdditional configuration
Route 53route53AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, [AWS_REGION], [AWS_HOSTED_ZONE_ID] or a configured user/instance IAM profile.Additional configuration
Sakura CloudsakuracloudSAKURACLOUD_ACCESS_TOKEN, SAKURACLOUD_ACCESS_TOKEN_SECRETAdditional configuration
ScalewayscalewaySCALEWAY_API_TOKENAdditional configuration
SelectelselectelSELECTEL_API_TOKENAdditional configuration
ServercowservercowSERVERCOW_USERNAME, SERVERCOW_PASSWORDAdditional configuration
Simply.comsimplySIMPLY_ACCOUNT_NAME, SIMPLY_API_KEYAdditional configuration
SonicsonicSONIC_USER_ID, SONIC_API_KEYAdditional configuration
StackpathstackpathSTACKPATH_CLIENT_ID, STACKPATH_CLIENT_SECRET, STACKPATH_STACK_IDAdditional configuration
Tencent Cloud DNStencentcloudTENCENTCLOUD_SECRET_ID, TENCENTCLOUD_SECRET_KEYAdditional configuration
TransIPtransipTRANSIP_ACCOUNT_NAME, TRANSIP_PRIVATE_KEY_PATHAdditional configuration
UKFast SafeDNSsafednsSAFEDNS_AUTH_TOKENAdditional configuration
UltradnsultradnsULTRADNS_USERNAME, ULTRADNS_PASSWORDAdditional configuration
VariomediavariomediaVARIOMEDIA_API_TOKENAdditional configuration
VegaDNSvegadnsSECRET_VEGADNS_KEY, SECRET_VEGADNS_SECRET, VEGADNS_URLAdditional configuration
VercelvercelVERCEL_API_TOKENAdditional configuration
VersioversioVERSIO_USERNAME, VERSIO_PASSWORDAdditional configuration
VinylDNSvinyldnsVINYLDNS_ACCESS_KEY, VINYLDNS_SECRET_KEY, VINYLDNS_HOSTAdditional configuration
VK CloudvkcloudVK_CLOUD_PASSWORD, VK_CLOUD_PROJECT_ID, VK_CLOUD_USERNAMEAdditional configuration
VscalevscaleVSCALE_API_TOKENAdditional configuration
VULTRvultrVULTR_API_KEYAdditional configuration
WebnameswebnamesWEBNAMES_API_KEYAdditional configuration
WebsupportwebsupportWEBSUPPORT_API_KEY, WEBSUPPORT_SECRETAdditional configuration
WEDOSwedosWEDOS_USERNAME, WEDOS_WAPI_PASSWORDAdditional configuration
Yandex 360yandex360YANDEX360_OAUTH_TOKEN, YANDEX360_ORG_IDAdditional configuration
Yandex CloudyandexcloudYANDEX_CLOUD_FOLDER_ID, YANDEX_CLOUD_IAM_TOKENAdditional configuration
YandexyandexYANDEX_PDD_TOKENAdditional configuration
Zone.eezoneeeZONEEE_API_USER, ZONEEE_API_KEYAdditional configuration
ZonomizonomiZONOMI_API_KEYAdditional configuration
External ProgramexecEXEC_PATHAdditional configuration
HTTP requesthttpreqHTTPREQ_ENDPOINT, HTTPREQ_MODE, HTTPREQ_USERNAME, HTTPREQ_PASSWORD 1Additional configuration
manualmanualnone, but you need to run Traefik interactively 4, turn on debug log to see instructions and press Enter.

delayBeforeCheck

By default, the provider verifies the TXT record before letting ACME verify. You can delay this operation by specifying a delay (in seconds) with delayBeforeCheck (value must be greater than zero). This option is useful when internal networks block external DNS queries.

resolvers

Use custom DNS servers to resolve the FQDN authority.

File (YAML)

  1. certificatesResolvers:
  2. myresolver:
  3. acme:
  4. # ...
  5. dnsChallenge:
  6. # ...
  7. resolvers:
  8. - "1.1.1.1:53"
  9. - "8.8.8.8:53"

File (TOML)

  1. [certificatesResolvers.myresolver.acme]
  2. # ...
  3. [certificatesResolvers.myresolver.acme.dnsChallenge]
  4. # ...
  5. resolvers = ["1.1.1.1:53", "8.8.8.8:53"]

CLI

  1. # ...
  2. --certificatesresolvers.myresolver.acme.dnschallenge.resolvers=1.1.1.1:53,8.8.8.8:53

Wildcard Domains

ACME V2 supports wildcard certificates. As described in Let’s Encrypt’s post wildcard certificates can only be generated through a DNS-01 challenge.

External Account Binding

  • kid: Key identifier from External CA
  • hmacEncoded: HMAC key from External CA, should be in Base64 URL Encoding without padding format

File (YAML)

  1. certificatesResolvers:
  2. myresolver:
  3. acme:
  4. # ...
  5. eab:
  6. kid: abc-keyID-xyz
  7. hmacEncoded: abc-hmac-xyz

File (TOML)

  1. [certificatesResolvers.myresolver.acme]
  2. # ...
  3. [certificatesResolvers.myresolver.acme.eab]
  4. kid = "abc-keyID-xyz"
  5. hmacEncoded = "abc-hmac-xyz"

CLI

  1. # ...
  2. --certificatesresolvers.myresolver.acme.eab.kid=abc-keyID-xyz
  3. --certificatesresolvers.myresolver.acme.eab.hmacencoded=abc-hmac-xyz

More Configuration

caServer

Required, Default=”https://acme-v02.api.letsencrypt.org/directory

The CA server to use:

Using the Let’s Encrypt staging server

File (YAML)

  1. certificatesResolvers:
  2. myresolver:
  3. acme:
  4. # ...
  5. caServer: https://acme-staging-v02.api.letsencrypt.org/directory
  6. # ...

File (TOML)

  1. [certificatesResolvers.myresolver.acme]
  2. # ...
  3. caServer = "https://acme-staging-v02.api.letsencrypt.org/directory"
  4. # ...

CLI

  1. # ...
  2. --certificatesresolvers.myresolver.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory
  3. # ...

storage

Required, Default=”acme.json”

The storage option sets the location where your ACME certificates are saved to.

File (YAML)

  1. certificatesResolvers:
  2. myresolver:
  3. acme:
  4. # ...
  5. storage: acme.json
  6. # ...

File (TOML)

  1. [certificatesResolvers.myresolver.acme]
  2. # ...
  3. storage = "acme.json"
  4. # ...

CLI

  1. # ...
  2. --certificatesresolvers.myresolver.acme.storage=acme.json
  3. # ...

ACME certificates are stored in a JSON file that needs to have a 600 file mode.

In Docker you can mount either the JSON file, or the folder containing it:

  1. docker run -v "/my/host/acme.json:/acme.json" traefik
  1. docker run -v "/my/host/acme:/etc/traefik/acme" traefik

Warning

For concurrency reasons, this file cannot be shared across multiple instances of Traefik.

certificatesDuration

Optional, Default=2160

The certificatesDuration option defines the certificates’ duration in hours. It defaults to 2160 (90 days) to follow Let’s Encrypt certificates’ duration.

Traefik cannot manage certificates with a duration lower than 1 hour.

File (YAML)

  1. certificatesResolvers:
  2. myresolver:
  3. acme:
  4. # ...
  5. certificatesDuration: 72
  6. # ...

File (TOML)

  1. [certificatesResolvers.myresolver.acme]
  2. # ...
  3. certificatesDuration=72
  4. # ...

CLI

  1. # ...
  2. --certificatesresolvers.myresolver.acme.certificatesduration=72
  3. # ...

certificatesDuration is used to calculate two durations:

  • Renew Period: the period before the end of the certificate duration, during which the certificate should be renewed.
  • Renew Interval: the interval between renew attempts.
Certificate DurationRenew PeriodRenew Interval
>= 1 year4 months1 week
>= 90 days30 days1 day
>= 7 days1 day1 hour
>= 24 hours6 hours10 min
< 24 hours20 min1 min

preferredChain

Optional, Default=””

Preferred chain to use.

If the CA offers multiple certificate chains, prefer the chain with an issuer matching this Subject Common Name. If no match, the default offered chain will be used.

File (YAML)

  1. certificatesResolvers:
  2. myresolver:
  3. acme:
  4. # ...
  5. preferredChain: 'ISRG Root X1'
  6. # ...

File (TOML)

  1. [certificatesResolvers.myresolver.acme]
  2. # ...
  3. preferredChain = "ISRG Root X1"
  4. # ...

CLI

  1. # ...
  2. --certificatesresolvers.myresolver.acme.preferredChain=ISRG Root X1
  3. # ...

keyType

Optional, Default=”RSA4096”

KeyType used for generating certificate private key. Allow value ‘EC256’, ‘EC384’, ‘RSA2048’, ‘RSA4096’, ‘RSA8192’.

File (YAML)

  1. certificatesResolvers:
  2. myresolver:
  3. acme:
  4. # ...
  5. keyType: 'RSA4096'
  6. # ...

File (TOML)

  1. [certificatesResolvers.myresolver.acme]
  2. # ...
  3. keyType = "RSA4096"
  4. # ...

CLI

  1. # ...
  2. --certificatesresolvers.myresolver.acme.keyType=RSA4096
  3. # ...

Fallback

If Let’s Encrypt is not reachable, the following certificates will apply:

  1. Previously generated ACME certificates (before downtime)
  2. Expired ACME certificates
  3. Provided certificates

Important

For new (sub)domains which need Let’s Encrypt authentication, the default Traefik certificate will be used until Traefik is restarted.


Using Traefik for Business Applications?

If you are using Traefik in your organization, consider our enterprise-grade solutions:

These tools help businesses discover, deploy, secure, and manage microservices and APIs easily, at scale, across any environment.


  1. More information about the HTTP message format can be found here.

  2. Providing credentials to your application.

  3. google/default.go

  4. docker stack remark: there is no way to support terminal attached to container when deploying with docker stack, so you might need to run container with docker run -it to generate certificates using manual provider.

  5. The Global API Key needs to be used, not the Origin CA Key.

  6. As explained in the LEGO hurricane configuration, each domain or wildcard (record name) needs a token. So each update of record name must be followed by an update of the HURRICANE_TOKENS variable, and a restart of Traefik.