So my little home API (served from my Raspberry Pi 3B) was working fine in a Docker container with DuckDNS + Let's Encrypt SSL until I did an upgrade to Docker Compose V2. Now when I run the V2 container I get this message:
Unable to obtain ACME certificate for domains "mysubdomain.duckdns.org": unable to generate a certificate for the domains [mysubdomain.duckdns.org]: acme: error: 429 :: POST :: https://acme-v02.api.letsencrypt.org/acme/new-order :: urn:ietf:params:acme:error:rateLimited :: Error creating new order :: too many certificates (5) already issued for this exact set of domains in the last 168 hours
Why did I get this error? I thought since I already have a valid working SSL cert Traefik would reuse it -- or does Traefik try to request a new cert every time I restart the container?
Another question: I also have a valid cert that was generated from Certbot that passed the DNS-01 challenge. Can I force Traefik to use this cert instead (the files inside /etc/letsencrypt/live/mysubdomain.duckdns.org
)?
UPDATE
After some more reading with help from reddit, I think I'm closer to a solution (to reuse the SSL cert instead of requesting a new one after every container restart). Here's my current config...
docker-compose.yml
version: "3.8"
services:
web:
...
labels:
- "traefik.enable=true"
- "traefik.http.routers.pi.rule=Host(`mysubdomain.duckdns.org`)"
- "traefik.http.routers.pi.tls=true"
- "traefik.http.routers.pi.tls.certresolver=myresolver"
traefik:
environment:
- DUCKDNS_TOKEN=<my_duckdns_token>
image: traefik:v2.10.4
ports:
- "80:80"
- "443:443"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
- "./src/traefik.yml:/etc/traefik/traefik.yml"
- "./letsencrypt:/letsencrypt"
traefik.yml
entryPoints:
web:
address: :80
http:
redirections:
entryPoint:
to: websecure
scheme: https
websecure:
address: :443
providers:
docker:
exposedByDefault: false
certificatesResolvers:
myresolver:
acme:
email: myduckdns@email.com
caserver: https://acme-staging-v02.api.letsencrypt.org/directory
#storage: /letsencrypt/acme.json
storage: /letsencrypt/acme.staging.json
dnsChallenge:
provider: duckdns
log:
level: DEBUG
I'm following the advice of the docs to use a staging server to get the cert first before requesting a real cert. After starting up the container, I do see the letsencrypt/acme.staging.json
file in the build context directory, and it contains "status": "valid"
-- does this mean everything's OK with getting the staging cert?
However, I'm seeing this in the log:
traefik | time="2023-09-01T09:31:22Z" level=debug msg="legolog: [INFO] [mysubdomain.duckdns.org] acme: use dns-01 solver"
traefik | time="2023-09-01T09:31:22Z" level=debug msg="legolog: [INFO] [mysubdomain.duckdns.org] acme: Preparing to solve DNS-01"
traefik | time="2023-09-01T09:31:23Z" level=debug msg="legolog: [INFO] [mysubdomain.duckdns.org] acme: Trying to solve DNS-01"
traefik | time="2023-09-01T09:31:23Z" level=debug msg="legolog: [INFO] [mysubdomain.duckdns.org] acme: Checking DNS record propagation using [127.0.0.11:53]"
traefik | time="2023-09-01T09:31:25Z" level=debug msg="legolog: [INFO] Wait for propagation [timeout: 1m0s, interval: 2s]"
traefik | time="2023-09-01T09:31:28Z" level=debug msg="legolog: [INFO] [mysubdomain.duckdns.org] The server validated our request"
traefik | time="2023-09-01T09:31:28Z" level=debug msg="legolog: [INFO] [mysubdomain.duckdns.org] acme: Cleaning DNS-01 challenge"
traefik | time="2023-09-01T09:31:28Z" level=debug msg="legolog: [INFO] [mysubdomain.duckdns.org] acme: Validations succeeded; requesting certificates"
traefik | time="2023-09-01T09:32:03Z" level=debug msg="legolog: [INFO] Wait for certificate [timeout: 30s, interval: 500ms]"
traefik | time="2023-09-01T09:32:04Z" level=debug msg="legolog: [INFO] [mysubdomain.duckdns.org] Server responded with a certificate."
traefik | time="2023-09-01T09:32:04Z" level=debug msg="Certificates obtained for domains [mysubdomain.duckdns.org]" providerName=myresolver.acme ACME CA="https://acme-staging-v02.api.letsencrypt.org/directory" routerName=pi@docker rule="Host(`mysubdomain.duckdns.org`)"
traefik | time="2023-09-01T09:32:04Z" level=debug msg="Configuration received: {\"http\":{},\"tcp\":{},\"udp\":{},\"tls\":{}}" providerName=myresolver.acme
traefik | time="2023-09-01T09:32:04Z" level=debug msg="No entryPoint defined for this router, using the default one(s) instead: [web websecure]" routerName=pi
traefik | time="2023-09-01T09:32:04Z" level=debug msg="Adding certificate for domain(s) mysubdomain.duckdns.org"
traefik | time="2023-09-01T09:32:06Z" level=debug msg="No default certificate, fallback to the internal generated certificate" tlsStoreName=default
Is it normal to get "No default certificate" warning when using the Let's Encrypt staging server?