Let's encrypt for *a lot* of domains automatically


I am trying to setup Traefik inside Docker Swarm to be able to request Let's encrypt certificates for any domain. We have a lot of small, low traffic websites running and each of them has it's own domain, so it's practically impossible (and would be really inconvenient too) to hardcode these as labels. Also domains are going to be added overtime and thus we need this to be done automatically.

So far, wildcard host is working properly and all domains are accessible, but we can't get certificates to work. The default Traefik self-signed certificate is of course generated so browser displays a warning, but is there a way to get Let's encrypt working? Inside logs, there is always warning about no domains being found and it seems to be skipping cert generation because of that.

I tried both DNS (DigitalOcean - seemed to be working according to logs) and HTTP challenge without any results.

Thank you!

Depending on your needs and DNS Server you can create wildcard certificates for every needed domain but only with DNS Challenge.
Can you give an example for those domains ?

1 Like

For a lot of domains wildcard is the way to go. You must use DNS challenge in order to get a wildcard certificate, that's just how it has to work in order to validate an entire domain (prove you control a domain vs. prove you control a host). I don't have a lot of domains, but I did just get Traefik 2.0 working with DNS challenge and letsencrypt to get a wildcard cert for my domain for ease of deployment with new docker services, using Cloudflare because Namecheap won't let me use their API due to only having 1 domain with them and not spending at least $50/yr.

I highly recommend using the Let's Encrypt staging server during development (and remember you'll be getting invalid certificates but which are signed by Fake Let's Encrypt with the correct domain name as opposed to the default Traefik cert). That way you don't have to worry about rate limits.

And this is all assuming that when you say domains, you really mean subdomains. Top level domains will all need their own certificate.

1 Like

Well, it can be possibly any domain. We have like 40 domains at the moment. Also TLD's are different.
When I tried DNS challenge with DigitalOcean provider and wildcard host, it warns me about no domains found in host and it somehow skips certificate generation. We absolutely need this to be automated because it is non-sense to manually defining domains in service labels.

@linucksrox And this is all assuming that when you say domains, you really mean subdomains. - No, it's not only subdomains unfortunately. Subdomains work perfectly but multiple domains don't.

I can post also some configs if you want, but I am not sure which one anymore after so many tries :smiley:

So you're trying to accomplish automating certificate generation for something like *.domain1.com, *.domain2.org, *.domain3.net?

Regarding the warning about no domains found in host, I don't know about DigitalOcean specifically but I did have to tweak some permissions when I set it up with Cloudflare. Basically Traefik's ACME client (lego) needs permission to read domains as well as edit DNS entries. In my case specifically my API key has 3 permissions: zone settings (read only), zone (read only), and DNS (edit).

You do have those domains already set up in DigitalOcean right?

Yes you are right, here is my router host configuration I initially tried:

- traefik.http.routers.worker.rule=HostRegexp(`{subdomain:([a-z\-]+\.)*}{domain:[a-z\-]+}.{tld:([a-z]+)}`)
- traefik.http.routers.worker-secure.rule=HostRegexp(`{subdomain:([a-z\-]+\.)*}{domain:[a-z\-]+}.{tld:([a-z]+)}`)

If I move the dot from subdomain between curly brackets like this it still doesn't matter. I can access all domains with HTTP and HTTPS, but no let's encrypt certificates are generated.

- traefik.http.routers.worker.rule=HostRegexp(`{subdomain:([a-z\-]+)*}.{domain:[a-z\-]+}.{tld:([a-z]+)}`)
- traefik.http.routers.worker-secure.rule=HostRegexp(`{subdomain:([a-z\-]+)*}.{domain:[a-z\-]+}.{tld:([a-z]+)}`)

I also tried just pure wildcard like this without any luck:

- traefik.http.routers.worker.rule=HostRegexp(`{catchall:.*}`)
- traefik.http.routers.worker-secure.rule=HostRegexp(`{catchall:.*}`)

DigitalOcean API key has all permissions (read+write) set up.
Of course dns challenge is setup

I'm not sure if it's possible to do this. The Traefik documentation mentions that certResolver is based on Host and HostSNI rules, but I don't know if this can work with HostRegexp rules (https://docs.traefik.io/v2.0/routing/routers/#certresolver). I'm thinking you might have to at least specify root domains.

- traefik.http.routers.domain1-secure.rule=Host(`*.domain1.com`)
- traefik.http.routers.domain2-secure.rule=Host(`*.domain2.org`)
- traefik.http.routers.domain3-secure.rule=Host(`*.domain3.net`)

I just hope there is another solution than hardcoding it. This was my biggest fear from the beginning. Not fun :confused:

For wildcard certificates you have to use:

- "traefik.http.routers.myrouter.tls.domains[0].main=*.foobar.com"

@ldez, would it make sense to add this example in our docs under https://deploy-preview-5819--traefik-doc.netlify.com/https/acme/#wildcard-domains?

  • "traefik.http.routers.myrouter.tls.domains[0].main=*.foobar.com"