How to continuously create/renew certificates without hitting limits?

Example certbot docker-compose.yml for use with Traefik's provider.http with inline TLS certificates. It will create LetsEncrypt certificates for all Hosts, Traefik will just see them as regular TLS certificate files in dynamic configuration. THIS IS NOT PRODUCTION READY.

version: '3.9'

  certbot:
    image: certbot/certbot
    entrypoint: ["/bin/sh", "-c"]
    command: 
      - |
        apk add curl pcre-tools jq

        WEBROOT=/webroot
        echo WEBROOT $$WEBROOT
        mkdir -p $$WEBROOT/.well-known/acme-challenge

        echo START WEBSERVER
        python -m http.server 80 --directory $$WEBROOT &
        /bin/sleep 2

        while true; do

          echo FETCH DOMAINS
          DOMAINS=$$( \
            curl --silent --max-time 5 http://user:pass@traefik_traefik:8080/api/http/routers | \
            pcregrep -o '(?<=Host\(`).*?(?=`\))' | sort | uniq \
          )
          echo FETCH DONE

          for NAME in $$DOMAINS; do
            echo DOMAIN $$NAME

            FILE=/.well-known/acme-challenge/traefik-certbot-$$EPOCHREALTIME
            touch $$WEBROOT$$FILE
            curl --silent --max-time 5 http://$$NAME$$FILE >> /dev/null
            ERR=$$?
            rm $$WEBROOT$$FILE

            if [ $$ERR -eq 0 ]; then
              echo DOMAIN CHALLENGE OK, RUN CERTBOT
              certbot certonly \
                --webroot -w $$WEBROOT \
                --non-interactive \
                --agree-tos \
                --no-eff-email \
                --keep-until-expiring \
                -m email@example.com \
                --quiet \
                --cert-name $$NAME \
                -d $$NAME
              if [ $$? -eq 0 ]; then
                echo CERTBOT OK $$NAME
              else
                echo CERTBOT FAILED $$NAME
              fi
            else
              echo DOMAIN CHALLENGE FAILED http://$$NAME$$FILE
            fi

          done

          echo TRAEFIK TLS FILE GENERATION
          FILE=$$WEBROOT/traefik-certbot.yml
          printf "tls:\n  options:\n    default:\n      minVersion: VersionTLS12\n  certificates:\n" > $$FILE
          for NAME in $$(find /etc/letsencrypt/live/ -maxdepth 1 -mindepth 1 -type d -print) ; do
            echo TRAEFIK TLS FILE ADD $$NAME
            printf "    # CERT FILE $$NAME\n" >> $$FILE
            printf "    - certFile: |-\n" >> $$FILE
            sed -e 's/^/        /' $$NAME/fullchain.pem >> $$FILE
            printf "      keyFile: |-\n" >> $$FILE
            sed -e 's/^/        /' $$NAME/privkey.pem >> $$FILE
          done

          #echo TREAFIK TLS FILE CONTENT
          #cat $$WEBROOT/traefik-certbot.yml

          echo SLEEP
          /bin/sleep 15
        done

    hostname: '{{.Node.Hostname}}'
    networks:
      - proxy
    volumes:
      - traefik-certificates:/etc/letsencrypt
    deploy:
      replicas: 1 # only single instance
      placement:
        constraints:
          - node.role==manager # for service discovery
      labels:
        - 'traefik.enable=true'
        - 'traefik.http.routers.certbot.entrypoints=web'
        - 'traefik.http.routers.certbot.rule=PathPrefix(`/.well-known/acme-challenge`)'
        - 'traefik.http.routers.certbot.priority=1024'
        - 'traefik.http.services.certbot.loadbalancer.server.port=80'

Pieces of the Traefik static configuration:

providers:
  docker:
    endpoint: "unix:///var/run/docker.sock"
    swarmMode: true
    exposedByDefault: false
    network: proxy
  
  # for dashboard
  file: 
    filename: /traefik-dynamic.yml
    watch: true

  # for LetsEncrypt certificates from certbot
  http: 
    endpoint: "http://traefik_certbot/traefik-certbot.yml"
    pollInterval: 15s
    pollTimeout: 5s
    
entryPoints:
  web:
    address: :80
    http:
      redirections:
        entryPoint:
          to: websecure
          scheme: https
          priority: 1000 # needed for certbot to be able to overrule
  websecure:
    ...

It's probably better to use a shared folder across all Traefik nodes and write the dynamic config file into the folder and use Traefik with watching provider.file instead. Then you could just copy and reference the certificates instead of inlining them. Be aware that the host folder needs to exist when running with Docker Swarm.