Hello there
I’m currently working on configuring Traefik to handle two distinct TLS profiles on separate entrypoints, but I’m running into an issue where only one profile is applied correctly (regular HTTPS) the other is completely ignored, despite being specified in the configuration. I tried specifying the TLS options both on entrypoint
and router
level, but the issue persists.
My goal is:
-
Serve regular HTTPS on port
443
using a certificate/key pair issued by a public CA (e.g., Comodo). -
Serve mutual TLS on port
8443
, requiring and validating client certificates issued by a local self-signed CA.
I’m using Docker Compose and have configured two main files:
docker-compose.yml
---
networks:
default:
driver: bridge
ipam:
config:
- subnet: ${SUBNET}
x-service-defaults: &service-defaults
security_opt:
- no-new-privileges:true
deploy:
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 5
window: 120s
services:
traefik:
<<: *service-defaults
image: docker.io/library/traefik:${TRAEFIK_DOCKER_TAG}
command:
- --accesslog.format=text
- --accesslog=true
- --api.basepath=/traefik
- --api.dashboard=true
- --api.insecure=false
- --entrypoints.mtls.address=:8443
- --entrypoints.mtls.http.tls.options=mtls@file
- --entrypoints.web-secure.address=:443
- --entrypoints.web-secure.http.tls.options=https@file
- --entrypoints.web.address=:80
- --entrypoints.web.http.redirections.entrypoint.permanent=true
- --entrypoints.web.http.redirections.entrypoint.scheme=https
- --entrypoints.web.http.redirections.entrypoint.to=web-secure
- --log.level=DEBUG
- --ping=true
- --providers.docker.exposedbydefault=false
- --providers.file.filename=/mnt/config/tls.toml
healthcheck:
test: ["CMD", "traefik", "healthcheck", "--ping"]
start_period: 10s
interval: 5s
timeout: 1s
retries: 5
networks:
default:
aliases:
- ${PUBLIC_FQDN}
ports:
- 80:80/tcp
- 8080:8080/tcp
- 443:443/tcp
- 8443:8443/tcp
volumes:
- ./config/traefik:/mnt/config:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
labels:
traefik.enable: true
traefik.http.middlewares.ipallowlist.ipallowlist.sourcerange: ${SUBNET}
traefik.http.routers.internal-dashboard.middlewares: ipallowlist
traefik.http.routers.internal-dashboard.entrypoints: web-secure
traefik.http.routers.internal-dashboard.rule: PathPrefix(`/traefik`)
traefik.http.routers.internal-dashboard.service: api@internal
grafana:
<<: *service-defaults
image: docker.io/grafana/grafana:${GRAFANA_DOCKER_TAG}
environment:
- PUBLIC_FQDN
- GF_SERVER_ROOT_URL=/grafana
- GF_SERVER_SERVE_FROM_SUB_PATH=true
- GF_USERS_ALLOW_SIGN_UP=false
healthcheck:
test: ["CMD", "wget", "--spider", "http://localhost:3000/api/health"]
start_period: 10s
interval: 5s
timeout: 1s
retries: 5
volumes:
- ./data/grafana:/var/lib/grafana
- ./config/grafana/provisioning:/etc/grafana/provisioning
labels:
traefik.enable: true
traefik.http.routers.grafana.entrypoints: web-secure
traefik.http.routers.grafana.rule: PathPrefix(`/grafana`)
# traefik.http.routers.grafana.tls.options: https@file
traefik.http.services.grafana.loadbalancer.server.port: 3000
prometheus:
<<: *service-defaults
image: docker.io/prom/prometheus:${PROMETHEUS_DOCKER_TAG}
command:
- --config.file=/etc/prometheus/config.yml
- --storage.tsdb.path=/usr/local/share/prometheus
- --web.external-url=https://${PUBLIC_FQDN}/prometheus
- --web.route-prefix=/prometheus/
environment:
- PUBLIC_FQDN
healthcheck:
test:
[
"CMD",
"wget",
"--spider",
"http://localhost:9090/prometheus/-/healthy",
]
start_period: 10s
interval: 5s
timeout: 1s
retries: 5
volumes:
- ./config/prometheus:/etc/prometheus
- ./data/prometheus:/usr/local/share/prometheus
labels:
traefik.enable: true
traefik.http.routers.prometheus.entrypoints: mtls
traefik.http.routers.prometheus.rule: PathPrefix(`/prometheus`)
# traefik.http.routers.prometheus.tls.options: mtls@file
traefik.http.services.prometheus.loadbalancer.server.port: 9090
tls.toml
[[tls.certificates]]
certFile = "/mnt/config/comodo.crt"
keyFile = "/mnt/config/comodo.key"
[tls.options]
[tls.options.https]
sniStrict = true
minVersion = "VersionTLS12"
[tls.options.mtls]
sniStrict = true
minVersion = "VersionTLS12"
[tls.options.mtls.clientAuth]
caFiles = ["/mnt/config/my-ca.crt"]
clientAuthType = "RequireAndVerifyClientCert"
Has anyone successfully implemented a similar setup? If so, could you please review what I might be missing or doing wrong?
Thank you very much in advance!