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 cannot 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:
certificatesResolvers:
myresolver:
# Enable ACME (Let's Encrypt): automatic SSL.
acme:
# Email address used for registration.
#
# Required
#
email: "[email protected]"
# File or key used for certificates storage.
#
# Required
#
storage: "acme.json"
# CA server to use.
# Uncomment the line to use Let's Encrypt's staging server,
# leave commented to go to prod.
#
# Optional
# Default: "https://acme-v02.api.letsencrypt.org/directory"
#
# caServer: "https://acme-staging-v02.api.letsencrypt.org/directory"
# The certificates' duration in hours.
# It defaults to 2160 (90 days) to follow Let's Encrypt certificates' duration.
#
# Optional
# Default: 2160
#
# certificatesDuration: 2160
# 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.
#
# Optional
# Default: ""
#
# preferredChain: 'ISRG Root X1'
# KeyType to use.
#
# Optional
# Default: "RSA4096"
#
# Available values : "EC256", "EC384", "RSA2048", "RSA4096", "RSA8192"
#
# keyType: RSA4096
# Use a TLS-ALPN-01 ACME challenge.
#
# Optional (but recommended)
#
tlsChallenge:
# Use a HTTP-01 ACME challenge.
#
# Optional
#
# httpChallenge:
# EntryPoint to use for the HTTP-01 challenges.
#
# Required
#
# entryPoint: web
# Use a DNS-01 ACME challenge rather than HTTP-01 challenge.
# Note: mandatory for wildcard certificate generation.
#
# Optional
#
# dnsChallenge:
# DNS provider used.
#
# Required
#
# provider: digitalocean
# 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.
# Useful if internal networks block external DNS queries.
#
# Optional
# Default: 0
#
# 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"
# Disable the DNS propagation checks before notifying ACME that the DNS challenge is ready.
#
# NOT RECOMMENDED:
# Increase the risk of reaching Let's Encrypt's rate limits.
#
# Optional
# Default: false
#
# disablePropagationCheck: true
# Enable ACME (Let's Encrypt): automatic SSL.
[certificatesResolvers.myresolver.acme]
# Email address used for registration.
#
# Required
#
email = "[email protected]"
# File or key used for certificates storage.
#
# Required
#
storage = "acme.json"
# CA server to use.
# Uncomment the line to use Let's Encrypt's staging server,
# leave commented to go to prod.
#
# Optional
# Default: "https://acme-v02.api.letsencrypt.org/directory"
#
# caServer = "https://acme-staging-v02.api.letsencrypt.org/directory"
# The certificates' duration in hours.
# It defaults to 2160 (90 days) to follow Let's Encrypt certificates' duration.
#
# Optional
# Default: 2160
#
# certificatesDuration=2160
# 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.
#
# Optional
# Default: ""
#
# preferredChain = "ISRG Root X1"
# KeyType to use.
#
# Optional
# Default: "RSA4096"
#
# Available values : "EC256", "EC384", "RSA2048", "RSA4096", "RSA8192"
#
# keyType = "RSA4096"
# Use a TLS-ALPN-01 ACME challenge.
#
# Optional (but recommended)
#
[certificatesResolvers.myresolver.acme.tlsChallenge]
# Use a HTTP-01 ACME challenge.
#
# Optional
#
# [certificatesResolvers.myresolver.acme.httpChallenge]
# EntryPoint to use for the HTTP-01 challenges.
#
# Required
#
# entryPoint = "web"
# Use a DNS-01 ACME challenge rather than HTTP-01 challenge.
# Note: mandatory for wildcard certificate generation.
#
# Optional
#
# [certificatesResolvers.myresolver.acme.dnsChallenge]
# DNS provider used.
#
# Required
#
# provider = "digitalocean"
# 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.
# Useful if internal networks block external DNS queries.
#
# Optional
# Default: 0
#
# 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"]
# Disable the DNS propagation checks before notifying ACME that the DNS challenge is ready.
#
# NOT RECOMMENDED:
# Increase the risk of reaching Let's Encrypt's rate limits.
#
# Optional
# Default: false
#
# disablePropagationCheck = true
# Enable ACME (Let's Encrypt): automatic SSL.
# Email address used for registration.
#
# Required
#
[email protected]
# File or key used for certificates storage.
#
# Required
#
--certificatesresolvers.myresolver.acme.storage=acme.json
# CA server to use.
# Uncomment the line to use Let's Encrypt's staging server,
# leave commented to go to prod.
#
# Optional
# Default: "https://acme-v02.api.letsencrypt.org/directory"
#
--certificatesresolvers.myresolver.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory
# The certificates' duration in hours.
# It defaults to 2160 (90 days) to follow Let's Encrypt certificates' duration.
#
# Optional
# Default: 2160
#
--certificatesresolvers.myresolver.acme.certificatesDuration=2160
# 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.
#
# Optional
# Default: ""
#
--certificatesresolvers.myresolver.acme.preferredchain="ISRG Root X1"
# KeyType to use.
#
# Optional
# Default: "RSA4096"
#
# Available values : "EC256", "EC384", "RSA2048", "RSA4096", "RSA8192"
#
--certificatesresolvers.myresolver.acme.keytype=RSA4096
# Use a TLS-ALPN-01 ACME challenge.
#
# Optional (but recommended)
#
--certificatesresolvers.myresolver.acme.tlschallenge=true
# Use a HTTP-01 ACME challenge.
#
# Optional
#
--certificatesresolvers.myresolver.acme.httpchallenge=true
# EntryPoint to use for the HTTP-01 challenges.
#
# Required
#
--certificatesresolvers.myresolver.acme.httpchallenge.entrypoint=web
# Use a DNS-01 ACME challenge rather than HTTP-01 challenge.
# Note: mandatory for wildcard certificate generation.
#
# Optional
#
--certificatesresolvers.myresolver.acme.dnschallenge=true
# DNS provider used.
#
# Required
#
--certificatesresolvers.myresolver.acme.dnschallenge.provider=digitalocean
# 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.
# Useful if internal networks block external DNS queries.
#
# Optional
# Default: 0
#
--certificatesresolvers.myresolver.acme.dnschallenge.delaybeforecheck=0
# Use following DNS servers to resolve the FQDN authority.
#
# Optional
# Default: empty
#
--certificatesresolvers.myresolver.acme.dnschallenge.resolvers=1.1.1.1:53,8.8.8.8:53
# Disable the DNS propagation checks before notifying ACME that the DNS challenge is ready.
#
# NOT RECOMMENDED:
# Increase the risk of reaching Let's Encrypt's rate limits.
#
# Optional
# Default: false
#
--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 themain
(and optionallysans
) option oftls.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 theHost()
matchers. Please note that multipleHost()
matchers can be used) for specifying multiple domain names for this router.
Please note that:
-
When multiple domain names are inferred from a given router, only one certificate is requested with the first domain name as the main domain, and the other domains as "SANs" (Subject Alternative Name).
-
As ACME V2 supports "wildcard domains", any router can provide a wildcard domain name, as "main" domain or as "SAN" domain.
Please check the configuration examples below for more details.
Configuration Examples¶
Enabling ACME
entryPoints:
web:
address: ":80"
websecure:
address: ":443"
certificatesResolvers:
myresolver:
acme:
email: [email protected]
storage: acme.json
httpChallenge:
# used during the challenge
entryPoint: web
[entryPoints]
[entryPoints.web]
address = ":80"
[entryPoints.websecure]
address = ":443"
[certificatesResolvers.myresolver.acme]
email = "[email protected]"
storage = "acme.json"
[certificatesResolvers.myresolver.acme.httpChallenge]
# used during the challenge
entryPoint = "web"
--entryPoints.web.address=:80
--entryPoints.websecure.address=:443
# ...
--certificatesresolvers.myresolver.acme.email=your-email@example.com
--certificatesresolvers.myresolver.acme.storage=acme.json
# used during the challenge
--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:
## Dynamic configuration
labels:
- traefik.http.routers.blog.rule=Host(`example.com`) && Path(`/blog`)
- traefik.http.routers.blog.tls=true
- traefik.http.routers.blog.tls.certresolver=myresolver
## Dynamic configuration
deploy:
labels:
- traefik.http.routers.blog.rule=Host(`example.com`) && Path(`/blog`)
- traefik.http.routers.blog.tls=true
- traefik.http.routers.blog.tls.certresolver=myresolver
- traefik.http.services.blog-svc.loadbalancer.server.port=8080"
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: blogtls
spec:
entryPoints:
- websecure
routes:
- match: Host(`example.com`) && Path(`/blog`)
kind: Rule
services:
- name: blog
port: 8080
tls:
certResolver: myresolver
labels: {
"traefik.http.routers.blog.rule": "Host(`example.com`) && Path(`/blog`)",
"traefik.http.routers.blog.tls": "true",
"traefik.http.routers.blog.tls.certresolver": "myresolver",
"traefik.http.services.blog-svc.loadbalancer.server.port": "8080"
}
## Dynamic configuration
labels:
- traefik.http.routers.blog.rule=Host(`example.com`) && Path(`/blog`)
- traefik.http.routers.blog.tls=true
- traefik.http.routers.blog.tls.certresolver=myresolver
## Dynamic configuration
http:
routers:
blog:
rule: "Host(`example.com`) && Path(`/blog`)"
tls:
certResolver: myresolver
## Dynamic configuration
[http.routers]
[http.routers.blog]
rule = "Host(`example.com`) && Path(`/blog`)"
[http.routers.blog.tls]
certResolver = "myresolver"
Multiple Domains from Router's Rule Example
- A certificate for the domains
example.com
(main) andblog.example.org
is requested:
## Dynamic configuration
labels:
- traefik.http.routers.blog.rule=(Host(`example.com`) && Path(`/blog`)) || Host(`blog.example.org`)
- traefik.http.routers.blog.tls=true
- traefik.http.routers.blog.tls.certresolver=myresolver
## Dynamic configuration
deploy:
labels:
- traefik.http.routers.blog.rule=(Host(`example.com`) && Path(`/blog`)) || Host(`blog.example.org`)
- traefik.http.routers.blog.tls=true
- traefik.http.routers.blog.tls.certresolver=myresolver
- traefik.http.services.blog-svc.loadbalancer.server.port=8080"
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: blogtls
spec:
entryPoints:
- websecure
routes:
- match: (Host(`example.com`) && Path(`/blog`)) || Host(`blog.example.org`)
kind: Rule
services:
- name: blog
port: 8080
tls:
certResolver: myresolver
labels: {
"traefik.http.routers.blog.rule": "(Host(`example.com`) && Path(`/blog`)) || Host(`blog.example.org`)",
"traefik.http.routers.blog.tls": "true",
"traefik.http.routers.blog.tls.certresolver": "myresolver",
"traefik.http.services.blog-svc.loadbalancer.server.port": "8080"
}
## Dynamic configuration
labels:
- traefik.http.routers.blog.rule=(Host(`example.com`) && Path(`/blog`)) || Host(`blog.example.org`)
- traefik.http.routers.blog.tls=true
- traefik.http.routers.blog.tls.certresolver=myresolver
## Dynamic configuration
http:
routers:
blog:
rule: "(Host(`example.com`) && Path(`/blog`)) || Host(`blog.example.org`)"
tls:
certResolver: myresolver
## Dynamic configuration
[http.routers]
[http.routers.blog]
rule = "(Host(`example.com`) && Path(`/blog`)) || Host(`blog.example.org`)"
[http.routers.blog.tls]
certResolver = "myresolver"
Multiple Domains from Router's tls.domain
Example
- A certificate for the domains
example.com
(main) and*.example.org
(SAN) is requested:
## Dynamic configuration
labels:
- traefik.http.routers.blog.rule=Host(`example.com`) && Path(`/blog`)
- traefik.http.routers.blog.tls=true
- traefik.http.routers.blog.tls.certresolver=myresolver
- traefik.http.routers.blog.tls.domains[0].main=example.com
- traefik.http.routers.blog.tls.domains[0].sans=*.example.org
## Dynamic configuration
deploy:
labels:
- traefik.http.routers.blog.rule=Host(`example.com`) && Path(`/blog`)
- traefik.http.services.blog-svc.loadbalancer.server.port=8080"
- traefik.http.routers.blog.tls=true
- traefik.http.routers.blog.tls.certresolver=myresolver
- traefik.http.routers.blog.tls.domains[0].main=example.com
- traefik.http.routers.blog.tls.domains[0].sans=*.example.org
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: blogtls
spec:
entryPoints:
- websecure
routes:
- match: Host(`example.com`) && Path(`/blog`)
kind: Rule
services:
- name: blog
port: 8080
tls:
certResolver: myresolver
domains:
- main: example.com
sans:
- '*.example.org'
labels: {
"traefik.http.routers.blog.rule": "Host(`example.com`) && Path(`/blog`)",
"traefik.http.routers.blog.tls": "true",
"traefik.http.routers.blog.tls.certresolver": "myresolver",
"traefik.http.routers.blog.tls.domains[0].main": "example.com",
"traefik.http.routers.blog.tls.domains[0].sans": "*.example.org",
"traefik.http.services.blog-svc.loadbalancer.server.port": "8080"
}
## Dynamic configuration
labels:
- traefik.http.routers.blog.rule=Host(`example.com`) && Path(`/blog`)
- traefik.http.routers.blog.tls=true
- traefik.http.routers.blog.tls.certresolver=myresolver
- traefik.http.routers.blog.tls.domains[0].main=example.com
- traefik.http.routers.blog.tls.domains[0].sans=*.example.org
## Dynamic configuration
http:
routers:
blog:
rule: "Host(`example.com`) && Path(`/blog`)"
tls:
certResolver: myresolver
domains:
- main: "example.com"
sans:
- "*.example.org"
## Dynamic configuration
[http.routers]
[http.routers.blog]
rule = "Host(`example.com`) && Path(`/blog`)"
[http.routers.blog.tls]
certResolver = "myresolver" # From static configuration
[[http.routers.blog.tls.domains]]
main = "example.com"
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
certificatesResolvers:
myresolver:
acme:
# ...
tlsChallenge: {}
[certificatesResolvers.myresolver.acme]
# ...
[certificatesResolvers.myresolver.acme.tlsChallenge]
# ...
--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
entryPoints:
web:
address: ":80"
websecure:
address: ":443"
certificatesResolvers:
myresolver:
acme:
# ...
httpChallenge:
entryPoint: web
[entryPoints]
[entryPoints.web]
address = ":80"
[entryPoints.websecure]
address = ":443"
[certificatesResolvers.myresolver.acme]
# ...
[certificatesResolvers.myresolver.acme.httpChallenge]
entryPoint = "web"
--entryPoints.web.address=:80
--entryPoints.websecure.address=:443
# ...
--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
certificatesResolvers:
myresolver:
acme:
# ...
dnsChallenge:
provider: digitalocean
delayBeforeCheck: 0
# ...
[certificatesResolvers.myresolver.acme]
# ...
[certificatesResolvers.myresolver.acme.dnsChallenge]
provider = "digitalocean"
delayBeforeCheck = 0
# ...
# ...
--certificatesresolvers.myresolver.acme.dnschallenge.provider=digitalocean
--certificatesresolvers.myresolver.acme.dnschallenge.delaybeforecheck=0
# ...
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:
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.org
with the bar
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 Name | Provider Code | Environment Variables | |
---|---|---|---|
ACME DNS | acme-dns |
ACME_DNS_API_BASE , ACME_DNS_STORAGE_PATH |
Additional configuration |
Alibaba Cloud | alidns |
ALICLOUD_ACCESS_KEY , ALICLOUD_SECRET_KEY , ALICLOUD_REGION_ID |
Additional configuration |
all-inkl | allinkl |
ALL_INKL_LOGIN , ALL_INKL_PASSWORD |
Additional configuration |
ArvanCloud | arvancloud |
ARVANCLOUD_API_KEY |
Additional configuration |
Auroradns | auroradns |
AURORA_USER_ID , AURORA_KEY , AURORA_ENDPOINT |
Additional configuration |
Autodns | autodns |
AUTODNS_API_USER , AUTODNS_API_PASSWORD |
Additional configuration |
Azure (DEPRECATED) | azure |
AZURE_CLIENT_ID , AZURE_CLIENT_SECRET , AZURE_SUBSCRIPTION_ID , AZURE_TENANT_ID , AZURE_RESOURCE_GROUP , [AZURE_METADATA_ENDPOINT] |
Additional configuration |
AzureDNS | azuredns |
AZURE_CLIENT_ID , AZURE_CLIENT_SECRET , AZURE_TENANT_ID , AZURE_SUBSCRIPTION_ID , AZURE_RESOURCE_GROUP , [AZURE_ENVIRONMENT] , [AZURE_PRIVATE_ZONE] , [AZURE_ZONE_NAME] |
Additional configuration |
Bindman | bindman |
BINDMAN_MANAGER_ADDRESS |
Additional configuration |
Blue Cat | bluecat |
BLUECAT_SERVER_URL , BLUECAT_USER_NAME , BLUECAT_PASSWORD , BLUECAT_CONFIG_NAME , BLUECAT_DNS_VIEW |
Additional configuration |
Brandit (DEPRECATED) | brandit |
BRANDIT_API_USERNAME , BRANDIT_API_KEY |
Additional configuration |
Bunny | bunny |
BUNNY_API_KEY |
Additional configuration |
Checkdomain | checkdomain |
CHECKDOMAIN_TOKEN , |
Additional configuration |
Civo | civo |
CIVO_TOKEN |
Additional configuration |
Cloud.ru | cloudru |
CLOUDRU_SERVICE_INSTANCE_ID , CLOUDRU_KEY_ID , CLOUDRU_SECRET |
Additional configuration |
CloudDNS | clouddns |
CLOUDDNS_CLIENT_ID , CLOUDDNS_EMAIL , CLOUDDNS_PASSWORD |
Additional configuration |
Cloudflare | cloudflare |
CF_API_EMAIL , CF_API_KEY 5 or CF_DNS_API_TOKEN , [CF_ZONE_API_TOKEN] |
Additional configuration |
ClouDNS | cloudns |
CLOUDNS_AUTH_ID , CLOUDNS_AUTH_PASSWORD |
Additional configuration |
CloudXNS (DEPRECATED) | cloudxns |
CLOUDXNS_API_KEY , CLOUDXNS_SECRET_KEY |
Additional configuration |
ConoHa | conoha |
CONOHA_TENANT_ID , CONOHA_API_USERNAME , CONOHA_API_PASSWORD |
Additional configuration |
Constellix | constellix |
CONSTELLIX_API_KEY , CONSTELLIX_SECRET_KEY |
Additional configuration |
Core-Networks | corenetworks |
CORENETWORKS_LOGIN , CORENETWORKS_PASSWORD |
Additional configuration |
CPanel and WHM | cpanel |
CPANEL_MODE , CPANEL_USERNAME , CPANEL_TOKEN , CPANEL_BASE_URL |
Additional configuration |
Derak Cloud | derak |
DERAK_API_KEY |
Additional configuration |
deSEC | desec |
DESEC_TOKEN |
Additional configuration |
DigitalOcean | digitalocean |
DO_AUTH_TOKEN |
Additional configuration |
DirectAdmin | directadmin |
DIRECTADMIN_API_URL , DIRECTADMIN_USERNAME , DIRECTADMIN_PASSWORD |
Additional configuration |
DNS Made Easy | dnsmadeeasy |
DNSMADEEASY_API_KEY , DNSMADEEASY_API_SECRET , DNSMADEEASY_SANDBOX |
Additional configuration |
dnsHome.de | dnsHomede |
DNSHOMEDE_CREDENTIALS |
Additional configuration |
DNSimple | dnsimple |
DNSIMPLE_OAUTH_TOKEN , DNSIMPLE_BASE_URL |
Additional configuration |
DNSPod | dnspod |
DNSPOD_API_KEY |
Additional configuration |
Domain Offensive (do.de) | dode |
DODE_TOKEN |
Additional configuration |
Domeneshop | domeneshop |
DOMENESHOP_API_TOKEN , DOMENESHOP_API_SECRET |
Additional configuration |
DreamHost | dreamhost |
DREAMHOST_API_KEY |
Additional configuration |
Duck DNS | duckdns |
DUCKDNS_TOKEN |
Additional configuration |
Dyn | dyn |
DYN_CUSTOMER_NAME , DYN_USER_NAME , DYN_PASSWORD |
Additional configuration |
Dynu | dynu |
DYNU_API_KEY |
Additional configuration |
EasyDNS | easydns |
EASYDNS_TOKEN , EASYDNS_KEY |
Additional configuration |
EdgeDNS | edgedns |
AKAMAI_CLIENT_TOKEN , AKAMAI_CLIENT_SECRET , AKAMAI_ACCESS_TOKEN |
Additional configuration |
Efficient IP | efficientip |
EFFICIENTIP_USERNAME , EFFICIENTIP_PASSWORD , EFFICIENTIP_HOSTNAME , EFFICIENTIP_DNS_NAME |
Additional configuration |
Epik | epik |
EPIK_SIGNATURE |
Additional configuration |
Exoscale | exoscale |
EXOSCALE_API_KEY , EXOSCALE_API_SECRET , EXOSCALE_ENDPOINT |
Additional configuration |
Fast DNS | fastdns |
AKAMAI_CLIENT_TOKEN , AKAMAI_CLIENT_SECRET , AKAMAI_ACCESS_TOKEN |
Additional configuration |
Freemyip.com | freemyip |
FREEMYIP_TOKEN |
Additional configuration |
G-Core | gcore |
GCORE_PERMANENT_API_TOKEN |
Additional configuration |
Gandi v5 | gandiv5 |
GANDIV5_PERSONAL_ACCESS_TOKEN |
Additional configuration |
Gandi | gandi |
GANDI_API_KEY |
Additional configuration |
Glesys | glesys |
GLESYS_API_USER , GLESYS_API_KEY , GLESYS_DOMAIN |
Additional configuration |
GoDaddy | godaddy |
GODADDY_API_KEY , GODADDY_API_SECRET |
Additional configuration |
Google Cloud DNS | gcloud |
GCE_PROJECT , Application Default Credentials 2 3, [GCE_SERVICE_ACCOUNT_FILE ] |
Additional configuration |
Google Domains | googledomains |
GOOGLE_DOMAINS_ACCESS_TOKEN |
Additional configuration |
Hetzner | hetzner |
HETZNER_API_KEY |
Additional configuration |
hosting.de | hostingde |
HOSTINGDE_API_KEY , HOSTINGDE_ZONE_NAME |
Additional configuration |
Hosttech | hosttech |
HOSTTECH_API_KEY |
Additional configuration |
http.net | httpnet |
HTTPNET_API_KEY |
Additional configuration |
Huawei Cloud | huaweicloud |
HUAWEICLOUD_ACCESS_KEY_ID , HUAWEICLOUD_SECRET_ACCESS_KEY , HUAWEICLOUD_REGION |
Additional configuration |
Hurricane Electric | hurricane |
HURRICANE_TOKENS 6 |
Additional configuration |
HyperOne | hyperone |
HYPERONE_PASSPORT_LOCATION , HYPERONE_LOCATION_ID |
Additional configuration |
IBM Cloud (SoftLayer) | ibmcloud |
SOFTLAYER_USERNAME , SOFTLAYER_API_KEY |
Additional configuration |
IIJ DNS Platform Service | iijdpf |
IIJ_DPF_API_TOKEN , IIJ_DPF_DPM_SERVICE_CODE |
Additional configuration |
IIJ | iij |
IIJ_API_ACCESS_KEY , IIJ_API_SECRET_KEY , IIJ_DO_SERVICE_CODE |
Additional configuration |
Infoblox | infoblox |
INFOBLOX_USERNAME , INFOBLOX_PASSWORD , INFOBLOX_HOST |
Additional configuration |
Infomaniak | infomaniak |
INFOMANIAK_ACCESS_TOKEN |
Additional configuration |
Internet.bs | internetbs |
INTERNET_BS_API_KEY , INTERNET_BS_PASSWORD |
Additional configuration |
INWX | inwx |
INWX_USERNAME , INWX_PASSWORD |
Additional configuration |
ionos | ionos |
IONOS_API_KEY |
Additional configuration |
IPv64 | ipv64 |
IPV64_API_KEY |
Additional configuration |
iwantmyname | iwantmyname |
IWANTMYNAME_USERNAME , IWANTMYNAME_PASSWORD |
Additional configuration |
Joker.com | joker |
JOKER_API_MODE with JOKER_API_KEY or JOKER_USERNAME , JOKER_PASSWORD |
Additional configuration |
Liara | liara |
LIARA_API_KEY |
Additional configuration |
Lightsail | lightsail |
AWS_ACCESS_KEY_ID , AWS_SECRET_ACCESS_KEY , DNS_ZONE |
Additional configuration |
Lima-City | limacity |
LIMACITY_API_KEY |
Additional configuration |
Linode v4 | linode |
LINODE_TOKEN |
Additional configuration |
Liquid Web | liquidweb |
LIQUID_WEB_PASSWORD , LIQUID_WEB_USERNAME , LIQUID_WEB_ZONE |
Additional configuration |
Loopia | loopia |
LOOPIA_API_PASSWORD , LOOPIA_API_USER |
Additional configuration |
LuaDNS | luadns |
LUADNS_API_USERNAME , LUADNS_API_TOKEN |
Additional configuration |
Mail-in-a-Box | mailinabox |
MAILINABOX_EMAIL , MAILINABOX_PASSWORD , MAILINABOX_BASE_URL |
Additional configuration |
Metaname | metaname |
METANAME_ACCOUNT_REFERENCE , METANAME_API_KEY |
Additional configuration |
mijn.host | mijnhost |
MIJNHOST_API_KEY |
Additional configuration |
Mittwald | mittwald |
MITTWALD_TOKEN |
Additional configuration |
MyDNS.jp | mydnsjp |
MYDNSJP_MASTER_ID , MYDNSJP_PASSWORD |
Additional configuration |
Mythic Beasts | mythicbeasts |
MYTHICBEASTS_USER_NAME , MYTHICBEASTS_PASSWORD |
Additional configuration |
name.com | namedotcom |
NAMECOM_USERNAME , NAMECOM_API_TOKEN , NAMECOM_SERVER |
Additional configuration |
Namecheap | namecheap |
NAMECHEAP_API_USER , NAMECHEAP_API_KEY |
Additional configuration |
Namesilo | namesilo |
NAMESILO_API_KEY |
Additional configuration |
NearlyFreeSpeech.NET | nearlyfreespeech |
NEARLYFREESPEECH_API_KEY , NEARLYFREESPEECH_LOGIN |
Additional configuration |
Netcup | netcup |
NETCUP_CUSTOMER_NUMBER , NETCUP_API_KEY , NETCUP_API_PASSWORD |
Additional configuration |
Netlify | netlify |
NETLIFY_TOKEN |
Additional configuration |
Nicmanager | nicmanager |
NICMANAGER_API_EMAIL , NICMANAGER_API_PASSWORD |
Additional configuration |
NIFCloud | nifcloud |
NIFCLOUD_ACCESS_KEY_ID , NIFCLOUD_SECRET_ACCESS_KEY |
Additional configuration |
Njalla | njalla |
NJALLA_TOKEN |
Additional configuration |
Nodion | nodion |
NODION_API_TOKEN |
Additional configuration |
NS1 | ns1 |
NS1_API_KEY |
Additional configuration |
Open Telekom Cloud | otc |
OTC_DOMAIN_NAME , OTC_USER_NAME , OTC_PASSWORD , OTC_PROJECT_NAME , OTC_IDENTITY_ENDPOINT |
Additional configuration |
Openstack Designate | designate |
OS_AUTH_URL , OS_USERNAME , OS_PASSWORD , OS_TENANT_NAME , OS_REGION_NAME |
Additional configuration |
Oracle Cloud | oraclecloud |
OCI_COMPARTMENT_OCID , OCI_PRIVKEY_FILE , OCI_PRIVKEY_PASS , OCI_PUBKEY_FINGERPRINT , OCI_REGION , OCI_TENANCY_OCID , OCI_USER_OCID |
Additional configuration |
OVH | ovh |
OVH_ENDPOINT , OVH_APPLICATION_KEY , OVH_APPLICATION_SECRET , OVH_CONSUMER_KEY , OVH_CLIENT_ID , OVH_CLIENT_SECRET |
Additional configuration |
Plesk | plesk |
PLESK_SERVER_BASE_URL , PLESK_USERNAME , PLESK_PASSWORD |
Additional configuration |
Porkbun | porkbun |
PORKBUN_SECRET_API_KEY , PORKBUN_API_KEY |
Additional configuration |
PowerDNS | pdns |
PDNS_API_KEY , PDNS_API_URL |
Additional configuration |
Rackspace | rackspace |
RACKSPACE_USER , RACKSPACE_API_KEY |
Additional configuration |
RcodeZero | rcodezero |
RCODEZERO_API_TOKEN |
Additional configuration |
reg.ru | regru |
REGRU_USERNAME , REGRU_PASSWORD |
Additional configuration |
Regfish | regfish |
regfish |
Additional configuration |
RFC2136 | rfc2136 |
RFC2136_TSIG_KEY , RFC2136_TSIG_SECRET , RFC2136_TSIG_ALGORITHM , RFC2136_NAMESERVER |
Additional configuration |
RimuHosting | rimuhosting |
RIMUHOSTING_API_KEY |
Additional configuration |
Route 53 | route53 |
AWS_ACCESS_KEY_ID , AWS_SECRET_ACCESS_KEY , [AWS_REGION] , [AWS_HOSTED_ZONE_ID] or a configured user/instance IAM profile. |
Additional configuration |
Sakura Cloud | sakuracloud |
SAKURACLOUD_ACCESS_TOKEN , SAKURACLOUD_ACCESS_TOKEN_SECRET |
Additional configuration |
Scaleway | scaleway |
SCW_API_TOKEN |
Additional configuration |
Selectel v2 | selectelv2 |
SELECTELV2_ACCOUNT_ID , SELECTELV2_PASSWORD , SELECTELV2_PROJECT_ID , SELECTELV2_USERNAME |
Additional configuration |
Selectel | selectel |
SELECTEL_API_TOKEN |
Additional configuration |
SelfHost.(de/eu) | selfhostde |
SELFHOSTDE_USERNAME , SELFHOSTDE_PASSWORD , SELFHOSTDE_RECORDS_MAPPING |
Additional configuration |
Servercow | servercow |
SERVERCOW_USERNAME , SERVERCOW_PASSWORD |
Additional configuration |
Shellrent | shellrent |
SHELLRENT_USERNAME , SHELLRENT_TOKEN |
Additional configuration |
Simply.com | simply |
SIMPLY_ACCOUNT_NAME , SIMPLY_API_KEY |
Additional configuration |
Sonic | sonic |
SONIC_USER_ID , SONIC_API_KEY |
Additional configuration |
Stackpath | stackpath |
STACKPATH_CLIENT_ID , STACKPATH_CLIENT_SECRET , STACKPATH_STACK_ID |
Additional configuration |
Technitium | technitium |
TECHNITIUM_SERVER_BASE_URL , TECHNITIUM_API_TOKEN |
Additional configuration |
Tencent Cloud DNS | tencentcloud |
TENCENTCLOUD_SECRET_ID , TENCENTCLOUD_SECRET_KEY |
Additional configuration |
Timeweb Cloud | timewebcloud |
TIMEWEBCLOUD_AUTH_TOKEN |
Additional configuration |
TransIP | transip |
TRANSIP_ACCOUNT_NAME , TRANSIP_PRIVATE_KEY_PATH |
Additional configuration |
UKFast SafeDNS | safedns |
SAFEDNS_AUTH_TOKEN |
Additional configuration |
Ultradns | ultradns |
ULTRADNS_USERNAME , ULTRADNS_PASSWORD |
Additional configuration |
Variomedia | variomedia |
VARIOMEDIA_API_TOKEN |
Additional configuration |
VegaDNS | vegadns |
SECRET_VEGADNS_KEY , SECRET_VEGADNS_SECRET , VEGADNS_URL |
Additional configuration |
Vercel | vercel |
VERCEL_API_TOKEN |
Additional configuration |
Versio | versio |
VERSIO_USERNAME , VERSIO_PASSWORD |
Additional configuration |
VinylDNS | vinyldns |
VINYLDNS_ACCESS_KEY , VINYLDNS_SECRET_KEY , VINYLDNS_HOST |
Additional configuration |
VK Cloud | vkcloud |
VK_CLOUD_PASSWORD , VK_CLOUD_PROJECT_ID , VK_CLOUD_USERNAME |
Additional configuration |
Volcano Engine | volcengine |
VOLC_ACCESSKEY , VOLC_SECRETKEY |
Additional configuration |
Vscale | vscale |
VSCALE_API_TOKEN |
Additional configuration |
VULTR | vultr |
VULTR_API_KEY |
Additional configuration |
Webnames | webnames |
WEBNAMES_API_KEY |
Additional configuration |
Websupport | websupport |
WEBSUPPORT_API_KEY , WEBSUPPORT_SECRET |
Additional configuration |
WEDOS | wedos |
WEDOS_USERNAME , WEDOS_WAPI_PASSWORD |
Additional configuration |
Yandex 360 | yandex360 |
YANDEX360_OAUTH_TOKEN , YANDEX360_ORG_ID |
Additional configuration |
Yandex Cloud | yandexcloud |
YANDEX_CLOUD_FOLDER_ID , YANDEX_CLOUD_IAM_TOKEN |
Additional configuration |
Yandex | yandex |
YANDEX_PDD_TOKEN |
Additional configuration |
Zone.ee | zoneee |
ZONEEE_API_USER , ZONEEE_API_KEY |
Additional configuration |
Zonomi | zonomi |
ZONOMI_API_KEY |
Additional configuration |
External Program | exec |
EXEC_PATH |
Additional configuration |
HTTP request | httpreq |
HTTPREQ_ENDPOINT , HTTPREQ_MODE , HTTPREQ_USERNAME , HTTPREQ_PASSWORD 1 |
Additional configuration |
manual | manual |
none, but you need to run Traefik interactively 4, turn on debug log to see instructions and press Enter. |
resolvers
¶
Use custom DNS servers to resolve the FQDN authority.
certificatesResolvers:
myresolver:
acme:
# ...
dnsChallenge:
# ...
resolvers:
- "1.1.1.1:53"
- "8.8.8.8:53"
[certificatesResolvers.myresolver.acme]
# ...
[certificatesResolvers.myresolver.acme.dnsChallenge]
# ...
resolvers = ["1.1.1.1:53", "8.8.8.8:53"]
# ...
--certificatesresolvers.myresolver.acme.dnschallenge.resolvers=1.1.1.1:53,8.8.8.8:53
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.
certificatesResolvers:
myresolver:
acme:
# ...
dnsChallenge:
# ...
delayBeforeCheck: 2s
[certificatesResolvers.myresolver.acme]
# ...
[certificatesResolvers.myresolver.acme.dnsChallenge]
# ...
delayBeforeCheck = "2s"
# ...
--certificatesresolvers.myresolver.acme.dnschallenge.delayBeforeCheck=2s
disablePropagationCheck
¶
Not recommended
Disable the TXT records propagation checks before notifying ACME that the DNS challenge is ready.
certificatesResolvers:
myresolver:
acme:
# ...
dnsChallenge:
# ...
disablePropagationCheck: true
[certificatesResolvers.myresolver.acme]
# ...
[certificatesResolvers.myresolver.acme.dnsChallenge]
# ...
disablePropagationCheck = true
# ...
--certificatesresolvers.myresolver.acme.dnschallenge.disablePropagationCheck=true
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 CAhmacEncoded
: HMAC key from External CA, should be in Base64 URL Encoding without padding format
certificatesResolvers:
myresolver:
acme:
# ...
eab:
kid: abc-keyID-xyz
hmacEncoded: abc-hmac-xyz
[certificatesResolvers.myresolver.acme]
# ...
[certificatesResolvers.myresolver.acme.eab]
kid = "abc-keyID-xyz"
hmacEncoded = "abc-hmac-xyz"
# ...
--certificatesresolvers.myresolver.acme.eab.kid=abc-keyID-xyz
--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:
- Let's Encrypt production server: https://acme-v02.api.letsencrypt.org/directory
- Let's Encrypt staging server: https://acme-staging-v02.api.letsencrypt.org/directory
Using the Let's Encrypt staging server
certificatesResolvers:
myresolver:
acme:
# ...
caServer: https://acme-staging-v02.api.letsencrypt.org/directory
# ...
[certificatesResolvers.myresolver.acme]
# ...
caServer = "https://acme-staging-v02.api.letsencrypt.org/directory"
# ...
# ...
--certificatesresolvers.myresolver.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory
# ...
storage
¶
Required, Default="acme.json"
The storage
option sets the location where your ACME certificates are saved to.
certificatesResolvers:
myresolver:
acme:
# ...
storage: acme.json
# ...
[certificatesResolvers.myresolver.acme]
# ...
storage = "acme.json"
# ...
# ...
--certificatesresolvers.myresolver.acme.storage=acme.json
# ...
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:
docker run -v "/my/host/acme.json:/acme.json" traefik
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
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.
It defaults to 2160
(90 days) to follow Let's Encrypt certificates' duration.
Certificate Duration | Renew Period | Renew Interval |
---|---|---|
>= 1 year | 4 months | 1 week |
>= 90 days | 30 days | 1 day |
>= 7 days | 1 day | 1 hour |
>= 24 hours | 6 hours | 10 min |
< 24 hours | 20 min | 1 min |
Traefik cannot manage certificates with a duration lower than 1 hour.
certificatesResolvers:
myresolver:
acme:
# ...
certificatesDuration: 72
# ...
[certificatesResolvers.myresolver.acme]
# ...
certificatesDuration=72
# ...
# ...
--certificatesresolvers.myresolver.acme.certificatesduration=72
# ...
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.
certificatesResolvers:
myresolver:
acme:
# ...
preferredChain: 'ISRG Root X1'
# ...
[certificatesResolvers.myresolver.acme]
# ...
preferredChain = "ISRG Root X1"
# ...
# ...
--certificatesresolvers.myresolver.acme.preferredChain=ISRG Root X1
# ...
keyType
¶
Optional, Default="RSA4096"
KeyType used for generating certificate private key. Allow value 'EC256', 'EC384', 'RSA2048', 'RSA4096', 'RSA8192'.
certificatesResolvers:
myresolver:
acme:
# ...
keyType: 'RSA4096'
# ...
[certificatesResolvers.myresolver.acme]
# ...
keyType = "RSA4096"
# ...
# ...
--certificatesresolvers.myresolver.acme.keyType=RSA4096
# ...
Fallback¶
If Let's Encrypt is not reachable, the following certificates will apply:
- Previously generated ACME certificates (before downtime)
- Expired ACME certificates
- 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 OSS in Production?
If you are using Traefik at work, consider adding enterprise-grade API gateway capabilities or commercial support for Traefik OSS.
Adding API Gateway capabilities to Traefik OSS is fast and seamless. There's no rip and replace and all configurations remain intact. See it in action via this short video.
-
More information about the HTTP message format can be found here. ↩
-
docker stack
remark: there is no way to support terminal attached to container when deploying withdocker stack
, so you might need to run container withdocker run -it
to generate certificates usingmanual
provider. ↩ -
The
Global API Key
needs to be used, not theOrigin CA Key
. ↩ -
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. ↩