1. The problem I’m having:
I am trying to set up caddy for a domain at hetzner. I want to use the DNS challenge but it does not seem to work.
2. Error messages and/or full log output:
This is the log I get when trying to start the container with docker compose up:
[+] Running 1/1
✔ Container caddy_hetzner Created 0.0s
Attaching to caddy_hetzner
caddy_hetzner | {"level":"info","ts":1771107262.685675,"msg":"maxprocs: Leaving GOMAXPROCS=2: CPU quota undefined"}
caddy_hetzner | {"level":"info","ts":1771107262.6867218,"msg":"GOMEMLIMIT is updated","package":"github.com/KimMachineGun/automemlimit/memlimit","GOMEMLIMIT":3691656806,"previous":9223372036854775807}
caddy_hetzner | {"level":"info","ts":1771107262.6868136,"msg":"using config from file","file":"/etc/caddy/Caddyfile"}
caddy_hetzner | {"level":"info","ts":1771107262.692738,"msg":"adapted config to JSON","adapter":"caddyfile"}
caddy_hetzner | {"level":"warn","ts":1771107262.6937575,"msg":"Caddyfile input is not formatted; run 'caddy fmt --overwrite' to fix inconsistencies","adapter":"caddyfile","file":"/etc/caddy/Caddyfile","line":2}
caddy_hetzner | {"level":"info","ts":1771107262.6953595,"logger":"admin","msg":"admin endpoint started","address":"localhost:2019","enforce_origin":false,"origins":["//[::1]:2019","//127.0.0.1:2019","//localhost:2019"]}
caddy_hetzner | {"level":"info","ts":1771107262.6958938,"logger":"http.auto_https","msg":"server is listening only on the HTTPS port but has no TLS connection policies; adding one to enable TLS","server_name":"srv0","https_port":443}
caddy_hetzner | {"level":"info","ts":1771107262.6959572,"logger":"http.auto_https","msg":"enabling automatic HTTP->HTTPS redirects","server_name":"srv0"}
caddy_hetzner | {"level":"info","ts":1771107262.6961644,"logger":"http","msg":"enabling HTTP/3 listener","addr":":443"}
caddy_hetzner | {"level":"info","ts":1771107262.6963875,"msg":"failed to sufficiently increase receive buffer size (was: 208 kiB, wanted: 7168 kiB, got: 416 kiB). See https://github.com/quic-go/quic-go/wiki/UDP-Buffer-Sizes for details."}
caddy_hetzner | {"level":"info","ts":1771107262.6966817,"logger":"http.log","msg":"server running","name":"srv0","protocols":["h1","h2","h3"]}
caddy_hetzner | {"level":"warn","ts":1771107262.6968331,"logger":"http","msg":"HTTP/2 skipped because it requires TLS","network":"tcp","addr":":80"}
caddy_hetzner | {"level":"warn","ts":1771107262.6968617,"logger":"http","msg":"HTTP/3 skipped because it requires TLS","network":"tcp","addr":":80"}
caddy_hetzner | {"level":"info","ts":1771107262.6968808,"logger":"http.log","msg":"server running","name":"remaining_auto_https_redirects","protocols":["h1","h2","h3"]}
caddy_hetzner | {"level":"info","ts":1771107262.6969173,"logger":"http","msg":"enabling automatic TLS certificate management","domains":["najan.de"]}
caddy_hetzner | {"level":"info","ts":1771107262.6978922,"msg":"autosaved config (load with --resume flag)","file":"/config/caddy/autosave.json"}
caddy_hetzner | {"level":"info","ts":1771107262.6979568,"msg":"serving initial configuration"}
caddy_hetzner | {"level":"info","ts":1771107262.6997995,"logger":"tls","msg":"storage cleaning happened too recently; skipping for now","storage":"FileStorage:/data/caddy","instance":"c5ea1217-d00a-4f3b-9f8e-9bfcc6349698","try_again":1771193662.6997967,"try_again_in":86399.999999098}
caddy_hetzner | {"level":"info","ts":1771107262.700024,"logger":"tls","msg":"finished cleaning storage units"}
caddy_hetzner | {"level":"info","ts":1771107262.7001064,"logger":"tls.cache.maintenance","msg":"started background certificate maintenance","cache":"0x15ab3e68f980"}
caddy_hetzner | {"level":"info","ts":1771107262.7018473,"logger":"tls.obtain","msg":"acquiring lock","identifier":"najan.de"}
caddy_hetzner | {"level":"info","ts":1771107262.7029355,"logger":"tls.obtain","msg":"lock acquired","identifier":"najan.de"}
caddy_hetzner | {"level":"info","ts":1771107262.7031226,"logger":"tls.obtain","msg":"obtaining certificate","identifier":"najan.de"}
caddy_hetzner | {"level":"info","ts":1771107262.7043765,"logger":"tls.issuance.acme","msg":"waiting on internal rate limiter","identifiers":["najan.de"],"ca":"https://acme-v02.api.letsencrypt.org/directory","account":""}
caddy_hetzner | {"level":"info","ts":1771107262.7044752,"logger":"tls.issuance.acme","msg":"done waiting on internal rate limiter","identifiers":["najan.de"],"ca":"https://acme-v02.api.letsencrypt.org/directory","account":""}
caddy_hetzner | {"level":"info","ts":1771107262.7045174,"logger":"tls.issuance.acme","msg":"using ACME account","account_id":"https://acme-v02.api.letsencrypt.org/acme/acct/3064071376","account_contact":[]}
caddy_hetzner | {"level":"info","ts":1771107264.616377,"msg":"trying to solve challenge","identifier":"najan.de","challenge_type":"dns-01","ca":"https://acme-v02.api.letsencrypt.org/directory"}
caddy_hetzner | {"level":"error","ts":1771107264.6971872,"msg":"cleaning up solver","identifier":"najan.de","challenge_type":"dns-01","error":"no memory of presenting a DNS record for \"_acme-challenge.najan.de\" (usually OK if presenting also failed)","stacktrace":"github.com/mholt/acmez/v3.(*Client).solveChallenges.func1\n\tgithub.com/mholt/acmez/v3@v3.1.2/client.go:318\ngithub.com/mholt/acmez/v3.(*Client).solveChallenges\n\tgithub.com/mholt/acmez/v3@v3.1.2/client.go:363\ngithub.com/mholt/acmez/v3.(*Client).ObtainCertificate\n\tgithub.com/mholt/acmez/v3@v3.1.2/client.go:136\ngithub.com/caddyserver/certmagic.(*ACMEIssuer).doIssue\n\tgithub.com/caddyserver/certmagic@v0.24.0/acmeissuer.go:489\ngithub.com/caddyserver/certmagic.(*ACMEIssuer).Issue\n\tgithub.com/caddyserver/certmagic@v0.24.0/acmeissuer.go:382\ngithub.com/caddyserver/caddy/v2/modules/caddytls.(*ACMEIssuer).Issue\n\tgithub.com/caddyserver/caddy/v2@v2.10.2/modules/caddytls/acmeissuer.go:288\ngithub.com/caddyserver/certmagic.(*Config).obtainCert.func2\n\tgithub.com/caddyserver/certmagic@v0.24.0/config.go:626\ngithub.com/caddyserver/certmagic.doWithRetry\n\tgithub.com/caddyserver/certmagic@v0.24.0/async.go:104\ngithub.com/caddyserver/certmagic.(*Config).obtainCert\n\tgithub.com/caddyserver/certmagic@v0.24.0/config.go:700\ngithub.com/caddyserver/certmagic.(*Config).ObtainCertAsync\n\tgithub.com/caddyserver/certmagic@v0.24.0/config.go:505\ngithub.com/caddyserver/certmagic.(*Config).manageOne.func1\n\tgithub.com/caddyserver/certmagic@v0.24.0/config.go:415\ngithub.com/caddyserver/certmagic.(*jobManager).worker\n\tgithub.com/caddyserver/certmagic@v0.24.0/async.go:73"}
caddy_hetzner | {"level":"error","ts":1771107264.9717643,"logger":"tls.obtain","msg":"could not get certificate from issuer","identifier":"najan.de","issuer":"acme-v02.api.letsencrypt.org-directory","error":"[najan.de] solving challenges: presenting for challenge: adding temporary record for zone \"najan.de.\": Unauthorized (401) (order=https://acme-v02.api.letsencrypt.org/acme/order/3064071376/480350499376) (ca=https://acme-v02.api.letsencrypt.org/directory)"}
caddy_hetzner | {"level":"error","ts":1771107264.971877,"logger":"tls.obtain","msg":"will retry","error":"[najan.de] Obtain: [najan.de] solving challenges: presenting for challenge: adding temporary record for zone \"najan.de.\": Unauthorized (401) (order=https://acme-v02.api.letsencrypt.org/acme/order/3064071376/480350499376) (ca=https://acme-v02.api.letsencrypt.org/directory)","attempt":1,"retrying_in":60,"elapsed":2.268876445,"max_duration":2592000}
At the same time, the API TOKEN seems to work since using
curl -H "Authorization: Bearer [MY TOKEN]" https://api.hetzner.cloud/v1/zones" successfully shows my dns zone.
3. Caddy version:
docker-compose exec caddy caddy version
gives me:
snap install docker # version 28.4.0, or
apt install docker-compose # version 1.29.2-1
4. How I installed and ran Caddy:
a. System environment:
I am trying to get caddy to work in a proxmox VM (ubuntu) with docker.
b. Command:
My Dockerfile looks like this:
FROM caddy:builder AS builder
RUN xcaddy build \
--with github.com/caddy-dns/hetzner/
FROM caddy:latest
COPY --from=builder /usr/bin/caddy /usr/bin/caddy
Then I try to start caddy using this:
docker build -t caddy-hetzner .
docker compose down && docker compose up -d
c. Service/unit/compose file:
services:
caddy:
build: .
container_name: caddy_hetzner
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile
- ./conf:/config
- ./site:/srv
- caddy_data:/data
- caddy_config:/config
environment:
- HETZNER_API_TOKEN=[MY TOKEN]
volumes:
caddy_data:
caddy_config:
d. My complete Caddy config:
najan.de {
respond "Hello World"
tls {
dns hetzner[MY TOKEN]
}
}