Local DNS with pihole

1. The problem I’m having:

I’m trying to use my pihole DNS setup to have local domain names to access my server. I’ve seen some tutorials using the .lan TLD, so I wanted to try that one. I already have some services exposed with a FQDN, but wanted to use a local domain for local services.

2. Error messages and/or full log output:

Jan 09 18:19:29 argus systemd[1]: Starting caddy.service - Caddy...
Jan 09 18:19:29 argus caddy[44754]: caddy.HomeDir=/var/lib/caddy
Jan 09 18:19:29 argus caddy[44754]: caddy.AppDataDir=/var/lib/caddy/.local/share/caddy
Jan 09 18:19:29 argus caddy[44754]: caddy.AppConfigDir=/var/lib/caddy/.config/caddy
Jan 09 18:19:29 argus caddy[44754]: caddy.ConfigAutosavePath=/var/lib/caddy/.config/caddy/autosave.json
Jan 09 18:19:29 argus caddy[44754]: caddy.Version=v2.9.0 h1:rteY8N18LsQn+2KVk6R10Vg/AlNsID1N/Ek9JLjm2yE=
Jan 09 18:19:29 argus caddy[44754]: runtime.GOOS=linux
Jan 09 18:19:29 argus caddy[44754]: runtime.GOARCH=arm64
Jan 09 18:19:29 argus caddy[44754]: runtime.Compiler=gc
Jan 09 18:19:29 argus caddy[44754]: runtime.NumCPU=4
Jan 09 18:19:29 argus caddy[44754]: runtime.GOMAXPROCS=4
Jan 09 18:19:29 argus caddy[44754]: runtime.Version=go1.23.4
Jan 09 18:19:29 argus caddy[44754]: os.Getwd=/
Jan 09 18:19:29 argus caddy[44754]: LANG=en_GB.UTF-8
Jan 09 18:19:29 argus caddy[44754]: PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
Jan 09 18:19:29 argus caddy[44754]: NOTIFY_SOCKET=/run/systemd/notify
Jan 09 18:19:29 argus caddy[44754]: HOME=/var/lib/caddy
Jan 09 18:19:29 argus caddy[44754]: LOGNAME=caddy
Jan 09 18:19:29 argus caddy[44754]: USER=caddy
Jan 09 18:19:29 argus caddy[44754]: INVOCATION_ID=f417422bfa8446f49c85cd498737e82b
Jan 09 18:19:29 argus caddy[44754]: JOURNAL_STREAM=8:188233
Jan 09 18:19:29 argus caddy[44754]: SYSTEMD_EXEC_PID=44754
Jan 09 18:19:29 argus caddy[44754]: {"level":"info","ts":1736443169.5385299,"msg":"using config from file","file":"/etc/caddy/Caddyfile"}
Jan 09 18:19:29 argus caddy[44754]: {"level":"info","ts":1736443169.549595,"msg":"adapted config to JSON","adapter":"caddyfile"}
Jan 09 18:19:29 argus caddy[44754]: {"level":"warn","ts":1736443169.5497081,"msg":"Caddyfile input is not formatted; run 'caddy fmt --overwrite' to fix inconsistencies","adapter":"caddyfile","file":"/etc/caddy/Caddyfile","line":10}
Jan 09 18:19:29 argus caddy[44754]: {"level":"info","ts":1736443169.556938,"logger":"admin","msg":"admin endpoint started","address":"localhost:2019","enforce_origin":false,"origins":["//localhost:2019","//[::1]:2019","//127.0.0.1:2019"]}
Jan 09 18:19:29 argus caddy[44754]: {"level":"info","ts":1736443169.5581186,"logger":"tls.cache.maintenance","msg":"started background certificate maintenance","cache":"0x4000628e80"}
Jan 09 18:19:29 argus caddy[44754]: {"level":"info","ts":1736443169.5586689,"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}
Jan 09 18:19:29 argus caddy[44754]: {"level":"info","ts":1736443169.5587845,"logger":"http.auto_https","msg":"enabling automatic HTTP->HTTPS redirects","server_name":"srv0"}
Jan 09 18:19:29 argus caddy[44754]: {"level":"warn","ts":1736443169.5588806,"logger":"http.auto_https","msg":"server is listening only on the HTTP port, so no automatic HTTPS will be applied to this server","server_name":"srv1","http_port":80}
Jan 09 18:19:29 argus caddy[44754]: {"level":"debug","ts":1736443169.5590627,"logger":"http.auto_https","msg":"adjusted config","tls":{"automation":{"policies":[{}]}},"http":{"servers":{"srv0":{"listen":[":443"],"routes":[{"handle":[{"handler":"subroute","routes":[{"handle":[{"handler":"reverse_proxy","upstreams":[{"dial":"192.168.0.102:8090"}]}]}]}],"terminal":true},{"handle":[{"handler":"subroute","routes":[{"handle":[{"handler":"reverse_proxy","upstreams":[{"dial":"192.168.0.102:5232"}]}]}]}],"terminal":true},{"handle":[{"handler":"subroute","routes":[{"handle":[{"handler":"reverse_proxy","upstreams":[{"dial":"192.168.0.102:5001"}]}]}]}],"terminal":true},{"handle":[{"handler":"subroute","routes":[{"handle":[{"handler":"reverse_proxy","upstreams":[{"dial":"192.168.0.102:3001"}]}]}]}],"terminal":true},{"handle":[{"handler":"subroute","routes":[{"handle":[{"handler":"reverse_proxy","upstreams":[{"dial":"192.168.0.101:2283"}]}]}]}],"terminal":true},{"handle":[{"handler":"subroute","routes":[{"handle":[{"handler":"reverse_proxy","upstreams":[{"dial":"192.168.0.102:800"}]}]}]}],"terminal":true},{"handle":[{"handler":"subroute","routes":[{"handle":[{"handler":"reverse_proxy","upstreams":[{"dial":"192.168.0.102:3000"}]}]}]}],"terminal":true}],"tls_connection_policies":[{}],"automatic_https":{}},"srv1":{"listen":[":80"],"routes":[{"handle":[{"handler":"subroute","routes":[{"handle":[{"handler":"reverse_proxy","upstreams":[{"dial":"localhost:1080"}]}]}]}],"terminal":true},{},{"handle":[{"handler":"subroute","routes":[{"handle":[{"handler":"vars","root":"/usr/share/caddy"},{"handler":"file_server","hide":["/etc/caddy/Caddyfile"]}]}]}],"terminal":true},{}],"automatic_https":{"disable":true}}}}}
Jan 09 18:19:29 argus caddy[44754]: {"level":"info","ts":1736443169.5654354,"logger":"http","msg":"enabling HTTP/3 listener","addr":":443"}
Jan 09 18:19:29 argus caddy[44754]: {"level":"debug","ts":1736443169.5683272,"logger":"http","msg":"starting server loop","address":"[::]:443","tls":true,"http3":true}
Jan 09 18:19:29 argus caddy[44754]: {"level":"info","ts":1736443169.5684323,"logger":"http.log","msg":"server running","name":"srv0","protocols":["h1","h2","h3"]}
Jan 09 18:19:29 argus caddy[44754]: {"level":"warn","ts":1736443169.5684953,"logger":"http","msg":"HTTP/3 skipped because it requires TLS","network":"tcp","addr":":80"}
Jan 09 18:19:29 argus caddy[44754]: {"level":"debug","ts":1736443169.5686493,"logger":"http","msg":"starting server loop","address":"[::]:80","tls":false,"http3":false}
Jan 09 18:19:29 argus caddy[44754]: {"level":"warn","ts":1736443169.5686831,"logger":"http","msg":"HTTP/2 skipped because it requires TLS","network":"tcp","addr":":80"}
Jan 09 18:19:29 argus caddy[44754]: {"level":"info","ts":1736443169.5687048,"logger":"http.log","msg":"server running","name":"srv1","protocols":["h1","h2","h3"]}
Jan 09 18:19:29 argus caddy[44754]: {"level":"info","ts":1736443169.5687315,"logger":"http","msg":"enabling automatic TLS certificate management","domains":["git.example.com","dashboard.example.com","calendar.example.com","dockge.example.lan","status.example.com","immich.example.com","ntfy.example.com"]}
Jan 09 18:19:29 argus caddy[44754]: {"level":"info","ts":1736443169.5850327,"logger":"tls","msg":"storage cleaning happened too recently; skipping for now","storage":"FileStorage:/var/lib/caddy/.local/share/caddy","instance":"a7e685a1-4b41-4667-ba77-b13de9d6bc8f","try_again":1736529569.585025,"try_again_in":86399.999997344}
Jan 09 18:19:29 argus caddy[44754]: {"level":"info","ts":1736443169.5855222,"logger":"tls","msg":"finished cleaning storage units"}
Jan 09 18:19:29 argus caddy[44754]: {"level":"debug","ts":1736443169.5887494,"logger":"tls.cache","msg":"added certificate to cache","subjects":["git.example.com"],"expiration":1744049981,"managed":true,"issuer_key":"acme-v02.api.letsencrypt.org-directory","hash":"c7bb1cb0d4cd3143281955f9cd8e2de0ebcd9f634dcf7304b8c36ea5f312245c","cache_size":1,"cache_capacity":10000}
Jan 09 18:19:29 argus caddy[44754]: {"level":"debug","ts":1736443169.5889208,"logger":"events","msg":"event","name":"cached_managed_cert","id":"2f1d8e10-2c21-45a3-9ab8-760a47bb7148","origin":"tls","data":{"sans":["git.example.com"]}}
Jan 09 18:19:29 argus caddy[44754]: {"level":"debug","ts":1736443169.593694,"logger":"tls.cache","msg":"added certificate to cache","subjects":["dashboard.example.com"],"expiration":1744049847,"managed":true,"issuer_key":"acme-v02.api.letsencrypt.org-directory","hash":"182b6b277fedeae084b73fb695508959090b0ef5669e70a4ecbb8b0b615f18f1","cache_size":2,"cache_capacity":10000}
Jan 09 18:19:29 argus caddy[44754]: {"level":"debug","ts":1736443169.5938687,"logger":"events","msg":"event","name":"cached_managed_cert","id":"1f3d45b5-8236-4934-bd0f-43526a5dc49e","origin":"tls","data":{"sans":["dashboard.example.com"]}}
Jan 09 18:19:29 argus caddy[44754]: {"level":"debug","ts":1736443169.5984626,"logger":"tls.cache","msg":"added certificate to cache","subjects":["calendar.example.com"],"expiration":1744049981,"managed":true,"issuer_key":"acme-v02.api.letsencrypt.org-directory","hash":"e5440c81c8fb4497caa8a68cec86746bb609c6d72ba67daacc39bf8198a9c1aa","cache_size":3,"cache_capacity":10000}
Jan 09 18:19:29 argus caddy[44754]: {"level":"debug","ts":1736443169.5986216,"logger":"events","msg":"event","name":"cached_managed_cert","id":"c5dc8e72-d966-4a92-bf22-88b0d9c87147","origin":"tls","data":{"sans":["calendar.example.com"]}}
Jan 09 18:19:29 argus caddy[44754]: {"level":"info","ts":1736443169.6148145,"logger":"tls.obtain","msg":"acquiring lock","identifier":"dockge.example.lan"}
Jan 09 18:19:29 argus caddy[44754]: {"level":"debug","ts":1736443169.6159241,"logger":"tls.cache","msg":"added certificate to cache","subjects":["status.example.com"],"expiration":1744107641,"managed":true,"issuer_key":"acme-v02.api.letsencrypt.org-directory","hash":"759e614e0e5be639e8af0c30dd958c7c8d94e4eff32b46f8a74e96c0f30e42ec","cache_size":4,"cache_capacity":10000}
Jan 09 18:19:29 argus caddy[44754]: {"level":"debug","ts":1736443169.6161091,"logger":"events","msg":"event","name":"cached_managed_cert","id":"a673f01c-77cf-4574-a25a-979414a433bc","origin":"tls","data":{"sans":["status.example.com"]}}
Jan 09 18:19:29 argus caddy[44754]: {"level":"info","ts":1736443169.6318808,"logger":"tls.obtain","msg":"lock acquired","identifier":"dockge.example.lan"}
Jan 09 18:19:29 argus caddy[44754]: {"level":"info","ts":1736443169.6324594,"logger":"tls.obtain","msg":"obtaining certificate","identifier":"dockge.example.lan"}
Jan 09 18:19:29 argus caddy[44754]: {"level":"debug","ts":1736443169.6325815,"logger":"events","msg":"event","name":"cert_obtaining","id":"e4d86ab4-6415-4251-b5c2-670d046907c6","origin":"tls","data":{"identifier":"dockge.example.lan"}}
Jan 09 18:19:29 argus caddy[44754]: {"level":"debug","ts":1736443169.6334152,"logger":"tls","msg":"created CSR","identifiers":["dockge.example.lan"],"san_dns_names":["dockge.example.lan"],"san_emails":[],"common_name":"","extra_extensions":0}
Jan 09 18:19:29 argus caddy[44754]: {"level":"debug","ts":1736443169.6355047,"logger":"tls.obtain","msg":"trying issuer 1/1","issuer":"acme-v02.api.letsencrypt.org-directory"}
Jan 09 18:19:29 argus caddy[44754]: {"level":"debug","ts":1736443169.6355357,"logger":"tls.cache","msg":"added certificate to cache","subjects":["immich.example.com"],"expiration":1744048700,"managed":true,"issuer_key":"acme-v02.api.letsencrypt.org-directory","hash":"43641a2226656852075c597753fe153649f305543f92f6919412301c810d72a9","cache_size":5,"cache_capacity":10000}
Jan 09 18:19:29 argus caddy[44754]: {"level":"debug","ts":1736443169.6356852,"logger":"events","msg":"event","name":"cached_managed_cert","id":"be94c0eb-b095-413f-8b63-b2f2b5a4b43b","origin":"tls","data":{"sans":["immich.example.com"]}}
Jan 09 18:19:29 argus caddy[44754]: {"level":"debug","ts":1736443169.637338,"logger":"http","msg":"using existing ACME account because key found in storage associated with email","email":"default","ca":"https://acme-v02.api.letsencrypt.org/directory"}
Jan 09 18:19:29 argus caddy[44754]: {"level":"debug","ts":1736443169.638468,"logger":"http","msg":"using existing ACME account because key found in storage associated with email","email":"","ca":"https://acme-v02.api.letsencrypt.org/directory"}
Jan 09 18:19:29 argus caddy[44754]: {"level":"info","ts":1736443169.6386802,"logger":"http","msg":"waiting on internal rate limiter","identifiers":["dockge.example.lan"],"ca":"https://acme-v02.api.letsencrypt.org/directory","account":""}
Jan 09 18:19:29 argus caddy[44754]: {"level":"info","ts":1736443169.6387324,"logger":"http","msg":"done waiting on internal rate limiter","identifiers":["dockge.example.lan"],"ca":"https://acme-v02.api.letsencrypt.org/directory","account":""}
Jan 09 18:19:29 argus caddy[44754]: {"level":"info","ts":1736443169.6388154,"logger":"http","msg":"using ACME account","account_id":"https://acme-v02.api.letsencrypt.org/acme/acct/2156821195","account_contact":[]}
Jan 09 18:19:29 argus caddy[44754]: {"level":"debug","ts":1736443169.6411812,"logger":"tls.cache","msg":"added certificate to cache","subjects":["ntfy.example.com"],"expiration":1744049981,"managed":true,"issuer_key":"acme-v02.api.letsencrypt.org-directory","hash":"91622b7e63db9c1f2b733e98465a0d6d5df80e50cdc5a130e245e8f8734db598","cache_size":6,"cache_capacity":10000}
Jan 09 18:19:29 argus caddy[44754]: {"level":"debug","ts":1736443169.641512,"logger":"events","msg":"event","name":"cached_managed_cert","id":"271a9c9b-f579-4d02-aacf-24904821901f","origin":"tls","data":{"sans":["ntfy.example.com"]}}
Jan 09 18:19:29 argus caddy[44754]: {"level":"info","ts":1736443169.6424608,"msg":"autosaved config (load with --resume flag)","file":"/var/lib/caddy/.config/caddy/autosave.json"}
Jan 09 18:19:29 argus caddy[44754]: {"level":"info","ts":1736443169.6427522,"msg":"serving initial configuration"}
Jan 09 18:19:29 argus systemd[1]: Started caddy.service - Caddy.
Jan 09 18:19:30 argus caddy[44754]: {"level":"debug","ts":1736443170.0863142,"msg":"http request","method":"GET","url":"https://acme-v02.api.letsencrypt.org/directory","headers":{"User-Agent":["Caddy/2.9.0 CertMagic acmez (linux; arm64)"]},"response_headers":{"Cache-Control":["public, max-age=0, no-cache"],"Content-Length":["746"],"Content-Type":["application/json"],"Date":["Thu, 09 Jan 2025 17:19:30 GMT"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]},"status_code":200}
Jan 09 18:19:30 argus caddy[44754]: {"level":"debug","ts":1736443170.086931,"msg":"creating order","account":"https://acme-v02.api.letsencrypt.org/acme/acct/2156821195","identifiers":["dockge.example.lan"]}
Jan 09 18:19:30 argus caddy[44754]: {"level":"debug","ts":1736443170.2360852,"msg":"http request","method":"HEAD","url":"https://acme-v02.api.letsencrypt.org/acme/new-nonce","headers":{"User-Agent":["Caddy/2.9.0 CertMagic acmez (linux; arm64)"]},"response_headers":{"Cache-Control":["public, max-age=0, no-cache"],"Date":["Thu, 09 Jan 2025 17:19:30 GMT"],"Link":["<https://acme-v02.api.letsencrypt.org/directory>;rel=\"index\""],"Replay-Nonce":["LPSR-4-sJxKpFBMekouGfcUku4t6TuxS6009W_lmdiVvaq_iwkM"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]},"status_code":200}
Jan 09 18:19:30 argus caddy[44754]: {"level":"debug","ts":1736443170.3820772,"msg":"http request","method":"POST","url":"https://acme-v02.api.letsencrypt.org/acme/new-order","headers":{"Content-Type":["application/jose+json"],"User-Agent":["Caddy/2.9.0 CertMagic acmez (linux; arm64)"]},"response_headers":{"Boulder-Requester":["2156821195"],"Cache-Control":["public, max-age=0, no-cache"],"Content-Length":["227"],"Content-Type":["application/problem+json"],"Date":["Thu, 09 Jan 2025 17:19:30 GMT"],"Link":["<https://acme-v02.api.letsencrypt.org/directory>;rel=\"index\""],"Replay-Nonce":["1QDIi77b1_3MisKXRlE9FLPbFB8YvUp4ux3QivpDT8QjfShDOgY"],"Server":["nginx"]},"status_code":400}
Jan 09 18:19:30 argus caddy[44754]: {"level":"error","ts":1736443170.382713,"logger":"tls.obtain","msg":"could not get certificate from issuer","identifier":"dockge.example.lan","issuer":"acme-v02.api.letsencrypt.org-directory","error":"HTTP 400 urn:ietf:params:acme:error:rejectedIdentifier - Invalid identifiers requested :: Cannot issue for \"dockge.example.lan\": Domain name does not end with a valid public suffix (TLD)"}
Jan 09 18:19:30 argus caddy[44754]: {"level":"debug","ts":1736443170.3828995,"logger":"events","msg":"event","name":"cert_failed","id":"a26ea969-2641-44c1-a5ba-0052b4ed0939","origin":"tls","data":{"error":{},"identifier":"dockge.example.lan","issuers":["acme-v02.api.letsencrypt.org-directory"],"renewal":false}}
Jan 09 18:19:30 argus caddy[44754]: {"level":"error","ts":1736443170.38316,"logger":"tls.obtain","msg":"will retry","error":"[dockge.example.lan] Obtain: [dockge.example.lan] creating new order: attempt 1: https://acme-v02.api.letsencrypt.org/acme/new-order: HTTP 400 urn:ietf:params:acme:error:rejectedIdentifier - Invalid identifiers requested :: Cannot issue for \"dockge.example.lan\": Domain name does not end with a valid public suffix (TLD) (ca=https://acme-v02.api.letsencrypt.org/directory)","attempt":1,"retrying_in":60,"elapsed":0.751175066,"max_duration":2592000}
Jan 09 18:20:05 argus caddy[44754]: {"level":"debug","ts":1736443205.2133508,"logger":"events","msg":"event","name":"tls_get_certificate","id":"452fa6aa-0ae1-4089-97d0-782fdad378ae","origin":"tls","data":{"client_hello":{"CipherSuites":[4866,4867,4865,49199,49195,49200,49196,158,49191,103,49192,107,163,159,52393,52392,52394,49327,49325,49315,49311,49245,49249,49239,49235,162,49326,49324,49314,49310,49244,49248,49238,49234,49188,106,49187,64,49162,49172,57,56,49161,49171,51,50,157,49313,49309,49233,156,49312,49308,49232,61,60,53,47,255],"ServerName":"calendar.example.com","SupportedCurves":[29,23,30,25,24,256,257,258,259,260],"SupportedPoints":"AAEC","SignatureSchemes":[1027,1283,1539,2055,2056,2057,2058,2059,2052,2053,2054,1025,1281,1537,771,769,770,1026,1282,1538],"SupportedProtos":null,"SupportedVersions":[772,771],"RemoteAddr":{"IP":"192.168.0.1","Port":41874,"Zone":""},"LocalAddr":{"IP":"192.168.0.100","Port":443,"Zone":""}}}}
Jan 09 18:20:05 argus caddy[44754]: {"level":"debug","ts":1736443205.2144687,"logger":"tls.handshake","msg":"choosing certificate","identifier":"calendar.example.com","num_choices":1}
Jan 09 18:20:05 argus caddy[44754]: {"level":"debug","ts":1736443205.2145207,"logger":"tls.handshake","msg":"default certificate selection results","identifier":"calendar.example.com","subjects":["calendar.example.com"],"managed":true,"issuer_key":"acme-v02.api.letsencrypt.org-directory","hash":"e5440c81c8fb4497caa8a68cec86746bb609c6d72ba67daacc39bf8198a9c1aa"}
Jan 09 18:20:05 argus caddy[44754]: {"level":"debug","ts":1736443205.2145824,"logger":"tls.handshake","msg":"matched certificate in cache","remote_ip":"192.168.0.1","remote_port":"41874","subjects":["calendar.example.com"],"managed":true,"expiration":1744049981,"hash":"e5440c81c8fb4497caa8a68cec86746bb609c6d72ba67daacc39bf8198a9c1aa"}
Jan 09 18:20:05 argus caddy[44754]: {"level":"debug","ts":1736443205.2286577,"logger":"http.handlers.reverse_proxy","msg":"selected upstream","dial":"192.168.0.102:5232","total_upstreams":1}
Jan 09 18:20:05 argus caddy[44754]: {"level":"debug","ts":1736443205.2342317,"logger":"http.handlers.reverse_proxy","msg":"upstream roundtrip","upstream":"192.168.0.102:5232","duration":0.004937083,"request":{"remote_ip":"192.168.0.1","remote_port":"41874","client_ip":"192.168.0.1","proto":"HTTP/1.1","method":"GET","host":"calendar.example.com","uri":"/","headers":{"User-Agent":["Uptime-Kuma/1.23.16"],"X-Forwarded-For":["192.168.0.1"],"Accept":["text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"],"X-Forwarded-Proto":["https"],"X-Forwarded-Host":["calendar.example.com"]},"tls":{"resumed":false,"version":772,"cipher_suite":4867,"proto":"","server_name":"calendar.example.com"}},"headers":{"Server":["WSGIServer/0.2 CPython/3.11.2"],"Location":["/.web"],"Content-Type":["text/plain; charset=utf-8"],"Date":["Thu, 09 Jan 2025 17:20:05 GMT"]},"status":302}
Jan 09 18:20:05 argus caddy[44754]: {"level":"debug","ts":1736443205.24433,"logger":"events","msg":"event","name":"tls_get_certificate","id":"160079d6-01b6-412a-ac5a-1347737fcc53","origin":"tls","data":{"client_hello":{"CipherSuites":[4866,4867,4865,49199,49195,49200,49196,158,49191,103,49192,107,163,159,52393,52392,52394,49327,49325,49315,49311,49245,49249,49239,49235,162,49326,49324,49314,49310,49244,49248,49238,49234,49188,106,49187,64,49162,49172,57,56,49161,49171,51,50,157,49313,49309,49233,156,49312,49308,49232,61,60,53,47,255],"ServerName":"calendar.example.com","SupportedCurves":[29,23,30,25,24,256,257,258,259,260],"SupportedPoints":"AAEC","SignatureSchemes":[1027,1283,1539,2055,2056,2057,2058,2059,2052,2053,2054,1025,1281,1537,771,769,770,1026,1282,1538],"SupportedProtos":null,"SupportedVersions":[772,771],"RemoteAddr":{"IP":"192.168.0.1","Port":41888,"Zone":""},"LocalAddr":{"IP":"192.168.0.100","Port":443,"Zone":""}}}}
Jan 09 18:20:05 argus caddy[44754]: {"level":"debug","ts":1736443205.244943,"logger":"tls.handshake","msg":"choosing certificate","identifier":"calendar.example.com","num_choices":1}
Jan 09 18:20:05 argus caddy[44754]: {"level":"debug","ts":1736443205.245046,"logger":"tls.handshake","msg":"default certificate selection results","identifier":"calendar.example.com","subjects":["calendar.example.com"],"managed":true,"issuer_key":"acme-v02.api.letsencrypt.org-directory","hash":"e5440c81c8fb4497caa8a68cec86746bb609c6d72ba67daacc39bf8198a9c1aa"}
Jan 09 18:20:05 argus caddy[44754]: {"level":"debug","ts":1736443205.2451055,"logger":"tls.handshake","msg":"matched certificate in cache","remote_ip":"192.168.0.1","remote_port":"41888","subjects":["calendar.example.com"],"managed":true,"expiration":1744049981,"hash":"e5440c81c8fb4497caa8a68cec86746bb609c6d72ba67daacc39bf8198a9c1aa"}
Jan 09 18:20:05 argus caddy[44754]: {"level":"debug","ts":1736443205.2582736,"logger":"http.handlers.reverse_proxy","msg":"selected upstream","dial":"192.168.0.102:5232","total_upstreams":1}
Jan 09 18:20:05 argus caddy[44754]: {"level":"debug","ts":1736443205.2628682,"logger":"http.handlers.reverse_proxy","msg":"upstream roundtrip","upstream":"192.168.0.102:5232","duration":0.00419724,"request":{"remote_ip":"192.168.0.1","remote_port":"41888","client_ip":"192.168.0.1","proto":"HTTP/1.1","method":"GET","host":"calendar.example.com","uri":"/.web","headers":{"X-Forwarded-For":["192.168.0.1"],"Accept":["text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"],"User-Agent":["Uptime-Kuma/1.23.16"],"X-Forwarded-Proto":["https"],"X-Forwarded-Host":["calendar.example.com"]},"tls":{"resumed":false,"version":772,"cipher_suite":4867,"proto":"","server_name":"calendar.example.com"}},"headers":{"Date":["Thu, 09 Jan 2025 17:20:05 GMT"],"Server":["WSGIServer/0.2 CPython/3.11.2"],"Location":["/.web/"],"Content-Type":["text/plain; charset=utf-8"]},"status":302}
Jan 09 18:20:05 argus caddy[44754]: {"level":"debug","ts":1736443205.272585,"logger":"events","msg":"event","name":"tls_get_certificate","id":"47558747-60dc-4c93-b215-64b29c9c59d6","origin":"tls","data":{"client_hello":{"CipherSuites":[4866,4867,4865,49199,49195,49200,49196,158,49191,103,49192,107,163,159,52393,52392,52394,49327,49325,49315,49311,49245,49249,49239,49235,162,49326,49324,49314,49310,49244,49248,49238,49234,49188,106,49187,64,49162,49172,57,56,49161,49171,51,50,157,49313,49309,49233,156,49312,49308,49232,61,60,53,47,255],"ServerName":"calendar.example.com","SupportedCurves":[29,23,30,25,24,256,257,258,259,260],"SupportedPoints":"AAEC","SignatureSchemes":[1027,1283,1539,2055,2056,2057,2058,2059,2052,2053,2054,1025,1281,1537,771,769,770,1026,1282,1538],"SupportedProtos":null,"SupportedVersions":[772,771],"RemoteAddr":{"IP":"192.168.0.1","Port":41892,"Zone":""},"LocalAddr":{"IP":"192.168.0.100","Port":443,"Zone":""}}}}
Jan 09 18:20:05 argus caddy[44754]: {"level":"debug","ts":1736443205.273175,"logger":"tls.handshake","msg":"choosing certificate","identifier":"calendar.example.com","num_choices":1}
Jan 09 18:20:05 argus caddy[44754]: {"level":"debug","ts":1736443205.273231,"logger":"tls.handshake","msg":"default certificate selection results","identifier":"calendar.example.com","subjects":["calendar.example.com"],"managed":true,"issuer_key":"acme-v02.api.letsencrypt.org-directory","hash":"e5440c81c8fb4497caa8a68cec86746bb609c6d72ba67daacc39bf8198a9c1aa"}
Jan 09 18:20:05 argus caddy[44754]: {"level":"debug","ts":1736443205.2732875,"logger":"tls.handshake","msg":"matched certificate in cache","remote_ip":"192.168.0.1","remote_port":"41892","subjects":["calendar.example.com"],"managed":true,"expiration":1744049981,"hash":"e5440c81c8fb4497caa8a68cec86746bb609c6d72ba67daacc39bf8198a9c1aa"}
Jan 09 18:20:05 argus caddy[44754]: {"level":"debug","ts":1736443205.283287,"logger":"http.handlers.reverse_proxy","msg":"selected upstream","dial":"192.168.0.102:5232","total_upstreams":1}
Jan 09 18:20:05 argus caddy[44754]: {"level":"debug","ts":1736443205.287919,"logger":"http.handlers.reverse_proxy","msg":"upstream roundtrip","upstream":"192.168.0.102:5232","duration":0.004346407,"request":{"remote_ip":"192.168.0.1","remote_port":"41892","client_ip":"192.168.0.1","proto":"HTTP/1.1","method":"GET","host":"calendar.example.com","uri":"/.web/","headers":{"X-Forwarded-For":["192.168.0.1"],"X-Forwarded-Proto":["https"],"X-Forwarded-Host":["calendar.example.com"],"Accept":["text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"],"User-Agent":["Uptime-Kuma/1.23.16"]},"tls":{"resumed":false,"version":772,"cipher_suite":4867,"proto":"","server_name":"calendar.example.com"}},"headers":{"Last-Modified":["Thu, 14 Jul 2022 20:24:16 GMT"],"Date":["Thu, 09 Jan 2025 17:20:05 GMT"],"Server":["WSGIServer/0.2 CPython/3.11.2"],"Content-Type":["text/html"]},"status":200}

3. Caddy version:

v2.9.0 h1:rteY8N18LsQn+2KVk6R10Vg/AlNsID1N/Ek9JLjm2yE=

4. How I installed and ran Caddy:

a. System environment:

Raspbian 64-bit, on a raspberry pi zero 2w
I installed caddy with sudo apt install caddy, after using the guide.
I’m running caddy through systemd

b. Command:

sudo systemctl start caddy

c. Service/unit/compose file:

[Unit]
Description=Caddy
Documentation=https://caddyserver.com/docs/
After=network.target network-online.target
Requires=network-online.target

[Service]
Type=notify
User=caddy
Group=caddy
ExecStart=/usr/bin/caddy run --environ --config /etc/caddy/Caddyfile
ExecReload=/usr/bin/caddy reload --config /etc/caddy/Caddyfile
TimeoutStopSec=5s
LimitNOFILE=1048576
LimitNPROC=512
PrivateTmp=true
ProtectSystem=full
AmbientCapabilities=CAP_NET_BIND_SERVICE

[Install]
WantedBy=multi-user.target

d. My complete Caddy config:

{
	debug
}

:80 {
	# Set this path to your site's directory.
	root * /usr/share/caddy

	# Enable the static file server.
	file_server

	# Another common task is to set up a reverse proxy:
	# reverse_proxy localhost:8080

	# Or serve a PHP site through php-fpm:
	# php_fastcgi localhost:9000
}

# Refer to the Caddy docs for more information:
# https://caddyserver.com/docs/caddyfile

# Internal services
dashboard.example.com {
	reverse_proxy 192.168.0.102:8090
}

status.example.com {
	reverse_proxy 192.168.0.102:3001
}

dockge.example.lan {
	reverse_proxy 192.168.0.102:5001
}

http://pi.hole {
	reverse_proxy localhost:1080
}

# External services
immich.example.com {
	reverse_proxy 192.168.0.101:2283
}

git.example.com {
	reverse_proxy 192.168.0.102:3000
}

calendar.example.com {
	reverse_proxy 192.168.0.102:5232
}

ntfy.example.com {
	reverse_proxy 192.168.0.102:800
}

5. Links to relevant resources:

I seem to have figured this out. My raspberry pi isn’t using itself as DNS server. This means that the DNS isn’t resolving, I’m not sure how to fix this, but I’m using another server as a caddy server now.

i dont know about .lan, but i was told to use .internal because no root servers will answer to that query.
someone can do something malicious with the other top level domains that could be dreamed up.

if the raspberry pi is running ubuntu or debian, you will need to add the dns server to /etc/resolv.conf

and that file may be automatically generated, so be sure to read the comments in the resolv.conf.

i use powerdns recursor, and powerdns authorative server, and i point the resolve to the recursor and the recursor forwards .internal to the authorative server, and everything else is resolved by adding extra lines to the resolv.conf (8.8.4.4 , 1.1.1.1 …) i would suggest using your ISP dns servers before the two i listed.
if you use powerdns, the documentation doesn’t really show much about forwarding, so this is what it looks like for my recursor

forward-zones=*.internal=10.4.0.3:5301, internal=10.4.0.3:5301

Thanks, it does seem like I didn’t use the pihole DNS for itself. I’ll try using resolv.conf and take a look at other domain names.