Traefik v2, docker, letsencrypt wildcard dns - can domains be specified in dynamic config?

I see a lot of examples/answers for specifying the domains as docker labels:

- "traefik.http.routers.traefik_https.tls.domains[0].main=domain.tld,"
- "traefik.http.routers.traefik_https.tls.domains[0].sans=*.domain.tld"

But I have a pile of docker services I want to set up and it would be nice to specify this centrally - having a wildcard domain but having to tell each service which domain to use seems inefficient.

The documentation for routers made me write this in my dyncamic config yaml

http:
 routers:
   router0:
    rule: "Host(`one.mydomain.tld`)"
     tls:
       certResolver: "http"
       domains:
         - main: "one.mydomain.tld"
           sans: "*.one.mydomain.tld"


 middlewares:
   https-redirect:
     redirectScheme:
       scheme: https

   default-headers:
     headers:
       frameDeny: true
       sslRedirect: true
       browserXssFilter: true
       contentTypeNosniff: true
       forceSTSHeader: true
       stsIncludeSubdomains: true
       stsPreload: true

   default-whitelist:
     ipWhiteList:
       sourceRange:
       - "10.0.0.0/24"
       - "192.168.0.0/16"
       - "172.0.0.0/8"
   # Allow only internal ip addresses

   secured:
     chain:
       middlewares:
       - default-whitelist
       - default-headers

But it's not clear how to tell docker to use this router0.

Help appreciated.

Sorry, I do not understand the question.

Can you elaborate, or may be give some examples? Inefficient in which way? If you want traefik to use let's encrypt to generate certificates for your router, you need to specify the certificate resolver (with acme being the only supported type for now). In many cases, your different routers will be matching different domains, so naturally you would want resolvers to generate different certificates. Of course if you decided to use the same wild card certificate, it's up to you and you can do that - traefik supports that. In that case you will need to specify that same certificate to fetch for each router you want this certificated to be used with. This also seems quite natural. Where do you see in-efficiency? If you have any particular measurements e.g. cpu increase or memory usage increase when you do that, please publish your metrics.

Again, not sure I understand. What you showed is traefik configuration, not docker configuration, so naturally you cannot tell docker to use router0, since it's not a concept docker is aware about. You use docker to manage image and containers, and you use traefik for routing.

I'm at a bit of a loss as to what you are tying to achieve.

Let me try and simplify. And I'll give some examples of how this was done in traefik v1.
So picture:

  • A single server
  • DNS set up for that server as one.mydomain.tld
  • DNS wildcard setup for that server as *.one.mydomain.tld
  • traefik setup with Letsencrypt on the server
  • several docker services running as:
    • service1.one.mydomain.tld
    • service2.one.mydomain.tld
    • service3.one.mydomain.tld

With this setup and traefik v1 you could define domains centrally in traefik.toml as part of an acme section:

[[acme.domains]]
main = "*.one.mydomain.tld"
sans = ["one.mydomain.tld"]

and you'd define the domain for a particular service via a docker label in docker-compose like so:

 - "traefik.frontend.rule=Host:portainer.one.mydomain.tld"

Traefik v1 will automagically generate valid LE certs for the subdomain. \o/

Now, most of the examples I see for traefik v2 show all of this config done in docker labels (see first code sample in OP above).

Which means if I run 10 different docker services I have to have 10 replicates of this same configuration - that's what I meant by inefficient, more work for me vs writing it once in traefik v1 :slight_smile:

It's possible to define middleware chains in traefik v2 dynamic config and then call them via docker labels, so calling https redirect to http middleware:

- "traefik.http.routers.portainer.middlewares=https-redirect@file"

And it looks to me from the routers configuration that I should be able to do similar, so define router as in second code block in OP above, then in the docker service labels section, something of like this:

  - "traefik.http.routers.portainer=router0@file"
  - "traefik.http.routers.portainer.rule=Host(`portainer.one.mydomain.tld`)"

I hope that's clearer. In essence I'm asking how to specify common router config in traefik dynamic configuration and include it from a docker label.

Just a clarification.

The sources of dynamic configuration are:

  • file (not the traefik.toml because in the v2 it contains only the static configuration.)
  • labels
  • k8s IngressRoute
  • ...

so labels are the dynamic configuration.

The dynamic configuration contains configuration for routers, services, middlewares and TLS (certs and options)

The static configuration contains mainly information about entry points and connections (providers, metrics, tracing, ...).

dynamic configuration:

static configuration:

In the v1 the domains are a part the static configuration and now in the v2 it's a part of the dynamic configuration.

The acme configuration is a part the static configuration in v1 and v2 (except domains) .

Right. But you can still define dynamic configuration in a file and include it from a docker label - at least for middleware...

You can reference an element (router, service, middleware) from a provider (e.g. file, docker,..) to another provider.

We call that provider namespace (myrouter@file, myrouter@docker), so a router defined in Docker can reference a service defined in a file.

But you cannot define a partial element (e.g. a part of a router configuration) in a file to include it in an existing element configuration. (e.g. you cannot merge 2 routers configuration)

1 Like

Thanks for the clarification.