So I have traefik
on traefik.example.com
and my-service
on example.com
in docker-swarm mode and I want to get and define Let's Encrypt certificate for example.com
and SAN for *.example.com
(tls/http challenge only). Other words any other services on www.example.com
, smth.example.com
etc. should work by https with this settings. What should I write in config?
Current configuration (doesn't work correct):
# docker-compose.traefik.yaml
version: '3.9'
services:
traefik:
image: traefik:v2.10
ports:
- 80:80
- 443:443
deploy:
restart_policy:
condition: on-failure
placement:
constraints:
- node.labels.certificate-storage == true
- node.role == manager
labels:
- traefik.enable=true
- traefik.http.middlewares.https-redirect.redirectscheme.scheme=https
- traefik.http.middlewares.https-redirect.redirectscheme.permanent=true
- traefik.http.routers.traefik-public-http.rule=Host(`traefik.example.com`)
- traefik.http.routers.traefik-public-http.entrypoints=http
- traefik.http.routers.traefik-public-http.middlewares=https-redirect
- traefik.http.routers.traefik-public-https.rule=Host(`traefik.example.com`)
- traefik.http.routers.traefik-public-https.entrypoints=https
- traefik.http.routers.traefik-public-https.tls=true
- traefik.http.routers.traefik-public-https.tls.certresolver=le
- traefik.http.routers.traefik-public-https.tls.domains[0].main=example.com
- traefik.http.routers.traefik-public-https.tls.domains[0].sans=*.example.com
- traefik.http.routers.traefik-public-https.service=api@internal
- traefik.http.services.traefik.loadbalancer.server.port=8080
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- traefik-public-certificates:/certificates
command:
- --providers.docker
- --providers.docker.exposedbydefault=false
- --providers.docker.swarmmode
- --entrypoints.http.address=:80
- --entrypoints.https.address=:443
- --certificatesresolvers.le.acme.email=test@gmail.com
- --certificatesresolvers.le.acme.storage=/certificates/acme.json
- --certificatesresolvers.le.acme.tlschallenge=true
networks:
- traefik-public
volumes:
traefik-public-certificates:
networks:
traefik-public:
driver: overlay
attachable: true
# docker-compose.yaml
version: "3.9"
services:
my-service:
image: my-service:latest
deploy:
replicas: 1
restart_policy:
condition: on-failure
labels:
- traefik.enable=true
- traefik.http.services.my-service.loadbalancer.server.port=8080
- traefik.http.middlewares.https-redirect.redirectscheme.scheme=https
- traefik.http.middlewares.https-redirect.redirectscheme.permanent=true
- traefik.http.routers.my-service-http.rule=Host(`example.com`)
- traefik.http.routers.my-service-http.entrypoints=http
- traefik.http.routers.my-service-http.middlewares=https-redirect
- traefik.http.routers.my-service-https.rule=Host(`example.com`)
- traefik.http.routers.my-service-https.entrypoints=https
- traefik.http.routers.my-service-https.tls=true
- traefik.http.routers.my-service-https.tls.certresolver=le
networks:
- traefik-public
networks:
traefik-public:
How many Docker Swarm managers do you have?
In general Traefik open source and LetsEncrypt only works with a single instance.
One manager. And all services in one node for now
For wildcards you need to use dnsChallenge, define via main/sans, see Traefik LE doc.
For a couple of sub-domains you can just get separate certs, AFAIK current LE limit is 50 different per week.
Yeah, separate certificates is my way for now. Anyway it's strange that Let's Encrypt provides wildcard SAN certificates, Traefik seems to provide them (by tls/http challenge) but I can't configure them
And one more question.
I don't understand why we describe SAN certificates for particular route?
- "traefik.http.routers.traefik-public-https.tls.domains[0].main=example.com"
- "traefik.http.routers.traefik-public-https.tls.domains[0].sans=traefik.example.com, www.example.com"
Looks like it should be in a global config because of we use certificate for domain, not for route (generally).
I also found config for SAN certificates looks like more correct
# traefik.yaml
certificatesResolvers:
le:
acme:
email: $EMAIL
storage: /acme.json
httpChallenge:
entryPoint: http
tlsChallenge:
keyType: "EC256"
domains:
- main: "example.com"
sans:
- "traefik.example.com"
- "www.example.com"
But why I can't describe this resolver inside command section of docker compose? Why I can set both httpChallenge and tlsChallenge? Is this gonna work? Why I have to set keyType
value instead of true
if we have default value (according doc)? Why this way of using SAN certificates doesn't work for me? Bad config or this is beta-feature?
You can declare certResolver
via command
, see doc.
AFAIK you can only use one type of challenge.
But I can't declare main/sans via CLI certResolver
Can I use defaultGeneratedCert
settings for my case?
command traefik error: failed to decode configuration from flags: field not found, node: tls
How about you search this forum, as this has been discussed and solved here many times before.
Note the [n] is an index, should be:
[0].main=example.com
[0].sans=*.example.com
My experiments show that this is the only way to get a SAN certificate:
#docker-compose.traefik (services.traefik.deploy.labels)
- traefik.http.routers.traefik.tls.domains[0].main=example.com
- traefik.http.routers.traefik.tls.domains[0].sans=sub1.example.com, sub2.example.com, etc.example.com
Asterisk template unfortunatelly doesn't work
- traefik.http.routers.traefik.tls.domains[0].sans=*.example.com
Unable to obtain ACME certificate for domains "example.com,.example.com"" rule="Host(traefik.example.com
)" error="unable to generate a certificate for the domains [example.com .example.com]: error: one or more domains had a problem:\n[.example.com] [.example.com] acme: could not determine solvers\n" routerName=traefik@docker providerName=le.acme ACME CA="https://acme-v02.api.letsencrypt.org/directory"
Did you try with quotes?
- "--entrypoints.websecure.http.tls.domains[0].main=${DOMAIN}"
- "--entrypoints.websecure.http.tls.domains[0].sans=*.${DOMAIN}"
Hello!
This is an old topic, but it is very relevant to me right now.
Why can’t I use global settings in traefik.yml?
It simply doesn’t work.
For example:
websecure:
address: ":443"
http:
tls:
certResolver: letencrypt
domains:
- main: example.com
sans:
- "*.example.com"
certificatesResolvers:
letencrypt:
acme:
email: e-mail@gmail.com
storage: /certs/acme.json
# caServer: https://acme-v02.api.letsencrypt.org/directory # production (default)
caServer: https://acme-staging-v02.api.letsencrypt.org/directory # staging
dnsChallenge:
provider: cloudflare
resolvers:
- 1.1.1.1:53
- 1.0.0.1:53
If I add labels, for example, to the Traefik service, then everything works perfectly:
- "traefik.http.routers.wildcard_cert.tls.certresolver=letencrypt"
- "traefik.http.routers.wildcard_cert.tls.domains[0].main=example.com"
- "traefik.http.routers.wildcard_cert.tls.domains[0].sans=*.example.com"
Here is the full configuration, but unfortunately, the wildcard certificate is not being issued.(
traefik.yml
global:
checkNewVersion: false
sendAnonymousUsage: false
entryPoints:
web:
address: ":80"
http:
redirections:
entrypoint:
to: websecure
scheme: https
websecure:
address: ":443"
http:
tls:
certResolver: letencrypt
domains:
- main: example.com
sans:
- "*.example.com"
log:
level: DEBUG
api:
insecure: true
dashboard: true
providers:
docker:
exposedByDefault: false
certificatesResolvers:
letencrypt:
acme:
email: e-mail@gmail.com
storage: /certs/acme.json
# caServer: https://acme-v02.api.letsencrypt.org/directory # production (default)
caServer: https://acme-staging-v02.api.letsencrypt.org/directory # staging
dnsChallenge:
provider: cloudflare
resolvers:
- 1.1.1.1:53
- 1.0.0.1:53
delayBeforeCheck: 20
I’m also interested in the answer to this question:
(Please don’t judge me for any mistakes; English is not my native language, and I’m using a translator.)
Best regards,
Alexander