Traefik’s wildcard certificate feature is surprisingly flexible and can often handle more than just direct subdomains like *.example.com.
Let’s see it in action. Imagine you have Traefik routing traffic for app1.example.com and app2.example.com, and you want a single certificate to cover both.
providers:
docker:
endpoint: "unix:///var/run/docker.sock"
exposedByDefault: false
file:
directory: /etc/traefik/dynamic_conf
watch: true
entryPoints:
web:
address: ":80"
http:
redirections:
entryPoint:
to: "websecure"
scheme: "https"
websecure:
address: ":443"
certificatesResolvers:
myresolver:
acme:
email: "your-email@example.com"
storage: "/etc/traefik/acme/acme.json"
httpChallenge:
entryPoint: "web"
# Dynamic configuration for services
# This would typically be in a separate file like /etc/traefik/dynamic_conf/services.yaml
# For demonstration, we'll embed it here.
# In a real-world scenario, you'd have separate service definitions.
Now, let’s define a Traefik service that leverages a wildcard certificate. The key is in the tls.certResolver and tls.domains configuration.
# Example service configuration (e.g., in /etc/traefik/dynamic_conf/app1.yaml)
http:
routers:
app1-router:
rule: "Host(`app1.example.com`)"
service: "app1-service"
entryPoints:
- "websecure"
tls:
certResolver: "myresolver"
domains:
- main: "example.com"
sans:
- "*.example.com"
services:
app1-service:
loadBalancer:
servers:
- url: "http://192.168.1.100:8080" # Replace with your actual service address
Here’s the crucial part: sans: ["*.example.com"]. When Traefik requests a certificate for main: "example.com", it includes *.example.com as a Subject Alternative Name (SAN). This single SAN entry tells the certificate authority (like Let’s Encrypt) that this certificate is valid for any subdomain under example.com.
So, when a request comes in for app1.example.com, Traefik checks its routers. It finds app1-router matches the host. It then looks at the TLS configuration. It sees certResolver: "myresolver", meaning it should get a certificate from Let’s Encrypt. The domains section specifies main: "example.com" and sans: ["*.example.com"]. Traefik will either use an existing certificate that covers example.com and *.example.com, or it will request a new one. Because *.example.com is present, this single certificate will be valid for app1.example.com.
The beauty of this is that you don’t need to define a separate certificate for app1.example.com, app2.example.com, or any other future subdomain. The wildcard SAN handles them all. You can even have multiple sans entries if you need to cover different wildcard patterns or specific subdomains alongside the wildcard.
The mental model is that Traefik acts as a unified TLS termination point. Instead of each application needing to manage its own certificate, Traefik centralizes this. The certResolver tells Traefik how to get certificates, and the domains configuration tells it what certificates it needs to obtain or possess. The wildcard in the sans field is simply a powerful pattern that instructs the CA to issue a certificate valid for a broad set of hostnames.
What most people don’t realize is that you can specify multiple SANs, and multiple wildcard patterns if necessary, within the same domains block. For instance, if you also needed to cover *.staging.example.com, you could add it as another entry in the sans list: sans: ["*.example.com", "*.staging.example.com"]. Traefik will then request a single certificate that covers both the apex domain and both wildcard patterns.
The next hurdle you’ll likely encounter is managing certificate renewals for a large number of wildcard domains and understanding the rate limits imposed by CAs like Let’s Encrypt.