I’m setting up Traefik to dynamically handle user-provided domains and generate custom TLS certificates manually and placing it inside a specific directory, then allowing traefik to auto-resolve https traffic without modifying traefik_dynamic.yml or restarting Traefik.
in my setup:
- users wil bind a custom domain to my IPv4 address (traefik container's 443)
- certificates will be generated by me externally (via Certbot, not ACME)
- certificates are stored in /etc/traefik/certs/{domain}/fullchain.pem and privkey.pem. i’m using providers.file.directory with watch: true to automatically detect changes.
my issue is, traefik still serves the default certificate (throws error for the new domain) even after adding a valid cert and key for a new domain in the above said directory (/etc/traefik/certs/{domain})
is traefik capable of watching certificate files dynamically and resolve tls traffic with the domain name set on the folder name inside /etc/traefik/certs (which is a custom directory where i keep all of user's certificates)? the problem is, i'm implementing this in a larger scale, and i can't be modifying traefik_dynamic.yml file each time to register a certificate directory.
is there any ways with which the domains can be dynamically registered, and traefik can auto-find the keys of the certificates with domain name sent in request, resolve https traffic without restarting traefik and dynamically modifying yml files?
my docker-compose.yaml:
services:
traefik:
image: traefik:v2.9
container_name: traefik
command:
- "--providers.docker=true"
- "--providers.file.directory=/etc/traefik/"
- "--providers.file.watch=true" # Enable automatic certificate detection
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
- "--certificatesresolvers.letsencrypt.acme.email=your-email@example.com"
- "--certificatesresolvers.letsencrypt.acme.storage=/etc/traefik/acme.json"
- "--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web"
- "--log.level=DEBUG"
ports:
- "80:80"
- "443:443"
- "8080:8080"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock"
- "./traefik.yml:/etc/traefik/traefik.yml"
- "./traefik_dynamic.yml:/etc/traefik/traefik_dynamic.yml"
- "./certs:/etc/traefik/certs" # Mount certificate directory
restart: always
my traefik.yml file:
global:
checkNewVersion: false
sendAnonymousUsage: false
log:
level: DEBUG # Options: ERROR, WARN, INFO, DEBUG
api:
dashboard: true # Enable Traefik Dashboard
insecure: true # ⚠️ Only for testing. Disable in production.
entryPoints:
web:
address: ":80"
websecure:
address: ":443"
providers:
docker:
exposedByDefault: false # Avoid exposing all containers automatically
file:
directory: "/etc/traefik" # Watching for certificate changes
watch: true # Enables automatic reload of certificates
my traefik_dynamic.yml file:
http:
routers:
nondocker:
entryPoints:
- web
- websecure
rule: "HostRegexp(`{subdomain:[a-z0-9-.]+}.domain.com`)"
service: someservice
middlewares:
- add-route-path # Attach middleware here
tls: {}
middlewares:
add-route-path:
replacePathRegex:
regex: "^/(.*)" # Match everything after /
replacement: "/route.php" # Rewrite request path to /route.php
services:
someservice:
loadBalancer:
servers:
- url: "http://somewhere:80"
tls:
certificates:
- certFile: "/etc/traefik/certs/domain.com/fullchain.pem"
keyFile: "/etc/traefik/certs/domain.com/privkey.pem"
stores:
default:
defaultCertificate:
certFile: "/etc/traefik/certs/domain.com/fullchain.pem"
keyFile: "/etc/traefik/certs/domain.com/privkey.pem"
options:
default:
minVersion: VersionTLS12