Hi there!
I recently bought a fully qualified domain name and I'm working on self-hosting a few services like Nextcloud, Immich, and others. My ISP only allows port forwarding for customers with static IPs, which I don’t want to use.
So, I thought of using Cloudflare Tunnel to access my services from anywhere, and it works great on its own. However, I wanted to challenge myself a bit and add Traefik into the mix, acting as a reverse proxy and an extra layer of control/security. I'm trying to avoid placing full trust in any single component.
That’s where things got a bit tricky.
A few days ago, I successfully generated TLS certificates using Let’s Encrypt with the dnsChallenge
method. But then I started wondering—since Cloudflare Tunnel uses its own certificates, and Traefik is using Let's Encrypt certs, would that create conflicts or unexpected behavior?
To try and fix that, I generated an Origin Certificate from Cloudflare, saved them as certificate.tld.pem
and key.tld.key
, and mounted them into my Traefik container.
Here’s my setup/config if you want to take a look.
Here is my docker-compose.yaml file
networks:
private:
external: false
public:
external: false
services:
cloudflared:
image: cloudflare/cloudflared:latest
container_name: cloudflared
hostname: cloudflared
restart: unless-stopped
command: tunnel run
networks:
- public
environment:
- TZ=${TZ}
- TUNNEL_TOKEN=${TUNNEL_TOKEN}
traefik:
image: traefik:latest
container_name: traefik
hostname: traefik
restart: unless-stopped
depends_on:
- cloudflared
security_opt:
- no-new-privileges:true
networks:
- public
- private
environment:
- TZ=${TZ}
- CF_API_EMAIL=${CF_API_EMAIL}
- CF_DNS_API_TOKEN=${CF_DNS_API_TOKEN}
ports:
- "80:80"
- "443:443"
volumes:
- /etc/localtime:/etc/localtime:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./config/traefik/traefik.yml:/etc/traefik/traefik.yml:ro
- ./config/traefik/certificate.tld.pem:/certificate.tld.pem:ro
- ./config/traefik/key.tld.key:/key.tld.key:ro
- ./config/traefik/certificates.yml:/certificates.yml
labels:
- "traefik.enable=true"
- "traefik.http.routers.dashboard.rule=Host(`traefik.mydomain.com`)"
- "traefik.http.routers.dashboard.entrypoints=websecure"
- "traefik.http.routers.dashboard.service=api@internal"
- "traefik.http.routers.dashboard.middlewares=dashboard-auth@docker"
- "traefik.http.middlewares.dashboard-auth.basicauth.users=user:pwd"
whoami:
image: traefik/whoami
container_name: whoami
restart: unless-stopped
depends_on:
- traefik
networks:
- private
labels:
- "traefik.enable=true"
- "traefik.http.routers.whoami.rule=Host(`whoami.mydomain.com`)"
- "traefik.http.routers.whoami.entrypoints=websecure"
- "traefik.http.routers.whoami.tls=true"
- "traefik.http.routers.whoami.service=whoami"
- "traefik.http.services.whoami.loadbalancer.server.port=80"
global:
checkNewVersion: true
sendAnonymousUsage: false
log:
level: DEBUG
metrics:
prometheus: true
api:
dashboard: true
debug: true
insecure: false
entrypoints:
websecure:
address: ":443"
http:
tls: {}
serversTransport:
insecureSkipVerify: false
providers:
docker:
endpoint: "unix:///var/run/docker.sock"
network: "public"
exposedByDefault: false
watch: true
file:
filename: /certificates.yml
watch: true
and here is the certificates.yml:
tls:
domains:
- main: "mydomain.com"
sans:
- "*.mydomain.com"
stores:
default:
defaultCertificates:
certFile: /certificate.tld.pem
keyFile: /key.tld.key
certificates:
- certFile: /certificate.tld.pem
keyFile: /key.tld.key
And here's the log that says traefik is using the default certificates:
traefik | 2025-07-28T14:28:48+03:00 DBG github.com/traefik/traefik/v3/pkg/server/configurationwatcher.go:227 > Configuration received config={"http":{"middlewares":{"dashboard-auth":{"basicAuth":{"users":["user:pwd"]}}},"routers":{"dashboard":{"entryPoints":["websecure"],"middlewares":["dashboard-auth@docker"],"rule":"Host(`traefik.mydomain.com`)","service":"api@internal"},"whoami":{"entryPoints":["websecure"],"rule":"Host(`whoami.mydomain.com`)","service":"whoami","tls":{}}},"services":{"traefik-homelab":{"loadBalancer":{"passHostHeader":true,"responseForwarding":{"flushInterval":"100ms"},"servers":[{"url":"http://172.19.0.2:80"}],"strategy":"wrr"}},"whoami":{"loadBalancer":{"passHostHeader":true,"responseForwarding":{"flushInterval":"100ms"},"servers":[{"url":"http://172.19.0.3:80"}],"strategy":"wrr"}}}},"tcp":{},"tls":{},"udp":{}} providerName=docker
traefik | 2025-07-28T14:28:48+03:00 DBG github.com/traefik/traefik/v3/pkg/tls/tlsmanager.go:321 > No default certificate, fallback to the internal generated certificate tlsStoreName=default
traefik | 2025-07-28T14:28:48+03:00 DBG github.com/traefik/traefik/v3/pkg/middlewares/metrics/metrics.go:50 > Creating middleware entryPointName=traefik middlewareName=metrics-entrypoint middlewareType=Metrics
traefik | 2025-07-28T14:28:48+03:00 DBG github.com/traefik/traefik/v3/pkg/middlewares/recovery/recovery.go:25 > Creating middleware entryPointName=traefik middlewareName=traefik-internal-recovery middlewareType=Recovery
traefik | 2025-07-28T14:28:48+03:00 DBG github.com/traefik/traefik/v3/pkg/middlewares/metrics/metrics.go:50 > Creating middleware entryPointName=websecure middlewareName=metrics-entrypoint middlewareType=Metrics
traefik | 2025-07-28T14:28:48+03:00 DBG github.com/traefik/traefik/v3/pkg/middlewares/metrics/metrics.go:50 > Creating middleware entryPointName=websecure middlewareName=metrics-entrypoint middlewareType=Metrics
traefik | 2025-07-28T14:28:48+03:00 DBG github.com/traefik/traefik/v3/pkg/middlewares/auth/basic_auth.go:37 > Creating middleware entryPointName=websecure middlewareName=dashboard-auth@docker middlewareType=BasicAuth routerName=dashboard@docker
traefik | 2025-07-28T14:28:48+03:00 DBG github.com/traefik/traefik/v3/pkg/middlewares/observability/middleware.go:33 > Adding tracing to middleware entryPointName=websecure middlewareName=dashboard-auth@docker routerName=dashboard@docker
traefik | 2025-07-28T14:28:48+03:00 DBG github.com/traefik/traefik/v3/pkg/server/service/service.go:320 > Creating load-balancer entryPointName=websecure routerName=whoami@docker serviceName=whoami@docker
traefik | 2025-07-28T14:28:48+03:00 DBG github.com/traefik/traefik/v3/pkg/server/service/service.go:363 > Creating server URL=http://**.**.**.**:80 entryPointName=websecure routerName=whoami@docker serverIndex=0 serviceName=whoami@docker
traefik | 2025-07-28T14:28:48+03:00 DBG github.com/traefik/traefik/v3/pkg/middlewares/metrics/metrics.go:82 > Creating middleware entryPointName=websecure middlewareName=metrics-service middlewareType=Metrics routerName=whoami@docker serviceName=whoami@docker
traefik | 2025-07-28T14:28:48+03:00 DBG github.com/traefik/traefik/v3/pkg/middlewares/observability/middleware.go:33 > Adding tracing to middleware entryPointName=websecure middlewareName=metrics-service routerName=whoami@docker serviceName=whoami@docker
traefik | 2025-07-28T14:28:48+03:00 DBG github.com/traefik/traefik/v3/pkg/middlewares/metrics/metrics.go:50 > Creating middleware entryPointName=websecure middlewareName=metrics-entrypoint middlewareType=Metrics
traefik | 2025-07-28T14:28:48+03:00 DBG github.com/traefik/traefik/v3/pkg/middlewares/recovery/recovery.go:25 > Creating middleware entryPointName=websecure middlewareName=traefik-internal-recovery middlewareType=Recovery
traefik | 2025-07-28T14:28:48+03:00 DBG github.com/traefik/traefik/v3/pkg/middlewares/metrics/metrics.go:50 > Creating middleware entryPointName=traefik middlewareName=metrics-entrypoint middlewareType=Metrics
traefik | 2025-07-28T14:28:48+03:00 DBG github.com/traefik/traefik/v3/pkg/server/router/tcp/manager.go:237 > Adding route for traefik.mydomain.com with TLS options default entryPointName=websecure
traefik | 2025-07-28T14:28:48+03:00 DBG github.com/traefik/traefik/v3/pkg/server/router/tcp/manager.go:237 > Adding route for whoami.mydomain.com with TLS options default entryPointName=websecure
traefik | 2025-07-28T14:28:55+03:00 DBG github.com/traefik/traefik/v3/pkg/tls/tlsmanager.go:228 > Serving default certificate for request: "*.mydomain.com"
traefik | 2025-07-28T14:28:55+03:00 DBG log/log.go:245 > http: TLS handshake error from **.**.**.**:36920: remote error: tls: bad certificate
Here's the cloudflared logs:
cloudflared | 2025-07-28T11:28:55Z ERR error="Unable to reach the origin service. The service may be down or it may not be responding to traffic from cloudflared: tls: failed to verify certificate: x509: certificate is valid for **.traefik.default, not *.mydomain.com" connIndex=3 event=1 ingressRule=0 originService=https://traefik
cloudflared | 2025-07-28T11:28:55Z ERR Request failed error="Unable to reach the origin service. The service may be down or it may not be responding to traffic from cloudflared: tls: failed to verify certificate: x509: certificate is valid for **.traefik.default, not *.mydomain.com" connIndex=3 dest=https://whoami.mydomain.com/ event=0 ip=****** type=http
I’ve been stuck on this issue for two weeks now and still haven’t been able to solve it. Really appreciate your help—thanks so much!