Traefik SSL/TLS Configuration

Traefik obtains and renews certificates through ACME certificate resolvers. Define a resolver in static config, then attach it to each router with tls.certResolver.

HTTP-01 challenge

entryPoints:
  web:
    address: ":80"
  websecure:
    address: ":443"

certificatesResolvers:
  myresolver:
    acme:
      email: [email protected]
      storage: acme.json
      httpChallenge:
        entryPoint: web

The HTTP challenge entrypoint must be reachable on port 80. Use Let's Encrypt staging while testing.

DNS-01 (Cloudflare)

certificatesResolvers:
  cloudflare:
    acme:
      email: [email protected]
      storage: acme.json
      dnsChallenge:
        provider: cloudflare
        resolvers:
          - "1.1.1.1:53"
          - "8.8.8.8:53"
# Env: CLOUDFLARE_DNS_API_TOKEN (Zone:Read + DNS:Edit)
# Staging: caServer: "https://acme-staging-v02.api.letsencrypt.org/directory"

Wildcards require DNS-01. Required for internal hostnames that are not publicly reachable on 80/443.

Attach resolver to a router

File provider

http:
  routers:
    app:
      rule: Host(`app.example.com`)
      service: app
      entryPoints:
        - websecure
      tls:
        certResolver: myresolver

Docker label

traefik.http.routers.app.tls.certresolver=myresolver

acme.json storage notes

  • Path comes from acme.storage (default acme.json)
  • File mode must be 600 or Traefik refuses to use it
  • Mount a directory volume; avoid bind-mounting an empty file that becomes a directory
  • Persist across restarts — a crash loop that re-requests certs can hit Let's Encrypt rate limits
  • Do not share one acme.json across multiple Traefik instances

🔗 See Also

Docs: doc.traefik.io — ACME