ACME renewal with some non-dockerized services handled by an external certbot

Hi,

I’m having some trouble with ACME ever since I migrated from another reverse proxy to traefik. Setup is:

  • a couple of dockerized web services
  • a non-dockerized mail server

All of these require ACME certificates. Previously, I solved this with a non-dockerized certbot that used a dockerized nginx as webroot. The system certbot put its challenges to a place under /var/www/ that the dockerized nginx serves up as mail.example.tld/.well-known/acme-challenge/…, and installation can be handled through standard certbot renewal hooks.

I haven’t been able to get this setup to work with traefik. I can either get traefik to handle certificates for the web services it reverse-proxies, or I can serve the webroot container, but not both. The problem seems to be that traefik feels responsible for all requests under /.well-known/acme-challenge instead of just those related to challenges it’s currently responding to, so if a traefik acme resolver is active, no other ACME challenge requests are passed through.

The documentation mentions an entryPoints.name.allowACMEByPass option that sounds like precisely what I need, but when I enable that, traefik’s own ACME resolver ceases to function and logs errors like

2025-09-05T12:17:26Z ERR Error renewing certificate from LE: {service.example.tld []} error="error: one or more domains had a problem:\n[service.example.tld] invalid authorization: acme: error: 403 :: urn:ietf:params:acme:error:unauthorized :: 2a01:4f8:c2c:d9ab::1: Invalid response from https://service.example.tld/.well-known/acme-challenge/DUHd4vqNRGRXjRmCDgchxTcVjAY49YUV944CDOvtwEc: 404\n" acmeCA=https://acme-v02.api.letsencrypt.org/directory providerName=webroot.acme

Right now I can choose between my mail server and my web services breaking every 90 days, which is slightly suboptimal.

My traefik.yml is reproduced below. front-net is a docker network to which all front-facing containers in the web services are attached, and /etc/traefik/sites.d only contains a special site configuration for Nextcloud AIO, where annotating the containers was not possible. As reproduced, the external certbot works but traefik doesn’t renew its own certificates. If I remove the allowACMEByPass options, traefik renews its own certificates but the external certbot’s challenges are not served because traefik intercepts the requests. I’m currently running traefik 3.5.1, but 90 days ago I had the same problem on 3.2 as well.

providers:
  docker:
    exposedByDefault: false
    network: front-net
  file:
    directory: /etc/traefik/sites.d
    watch: true

entryPoints:
  web:
    address: :80
    allowACMEByPass: true
    http:
      redirections:
        entrypoint:
          to: websecure
          scheme: https
  websecure:
    address: :443
    allowACMEByPass: true

certificatesResolvers:
  webroot:
    acme:
      email: webmaster@example.tld
      storage: /etc/traefik/acme.json
      httpChallenge:
        entryPoint: web

The webroot service for the external certbot is configured as follows:

services:
  www-server:
    image: docker.io/library/nginx:mainline
    container_name: www-server
    restart: unless-stopped
    networks:
      - front-net
    environment:
      TZ: Europe/Berlin
    volumes:
      - templates:/etc/nginx/templates
      - website:/data
      - /var/www/html/.well-known/acme-challenge:/data/.well-known/acme-challenge
    labels:
      - traefik.enable=true
      - traefik.http.routers.www.rule=Host(`mail.example.tld`)
      - traefik.http.routers.www.entrypoints=websecure,web
      - traefik.http.routers.www.tls=true
      - traefik.http.routers.www.tls.certresolver=webroot

Am I just reading the docs wrong, or is this use case just not supported?

Usually you would use different LetsEncrypt challenge types. When Traefik controls entrypoint 443, use tlsChallenge. For certbot behind Traefik, use httpChallenge, but ensure it can pass through and is not redirected to https. Or use dnsChallenge, which is independent.