Caddy on Raspberry Pi won't load index.html via IP?

1. The problem I’m having:

I am trying to set up a webserver with Caddy on my Raspberry Pi 5 following this tutorial.

The goal is to host my own Discourse forum (hence the subdomain “forum.twogeeksonecup.wtf”

I have edited the caddyfile like this:

> # The Caddyfile is an easy way to configure your Caddy web server.
> #
> # Unless the file starts with a global options block, the first
> # uncommented line is always the address of your site.
> #
> # To use your own domain name (with automatic HTTPS), first make
> # sure your domain's A/AAAA DNS records are properly pointed to
> # this machine's public IP, then replace ":80" below with your
> # domain name.
> 
> forum.twogeeksonecup.wtf {
> 	# Set this path to your site's directory.
> 	root * /var/www/html
> 	# gzip
> 	# 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

I have also added an index.html as a test within /var/www/html/.
When I open my IP adress on another computer it shows the “Congratulations”-page from Caddy but shouldnt it be resolving the index.html instead?

I have opened up the ports 80 and 443 on my router.

2. Error messages and/or full log output:

This is the caddy status I receive via systemctl status caddy

> ● caddy.service - Caddy
>      Loaded: loaded (/lib/systemd/system/caddy.service; enabled; preset: enabled)
>      Active: active (running) since Wed 2025-04-16 11:33:17 CEST; 35min ago
>        Docs: https://caddyserver.com/docs/
>     Process: 38848 ExecReload=/usr/bin/caddy reload --config /etc/caddy/Caddyfile --force (code=exited, status=0/SUCCESS)
>    Main PID: 37133 (caddy)
>       Tasks: 9 (limit: 19020)
>         CPU: 698ms
>      CGroup: /system.slice/caddy.service
>              └─37133 /usr/bin/caddy run --environ --config /etc/caddy/Caddyfile
> 
> Apr 16 12:08:14 raspberrypi caddy[37133]: {"level":"info","ts":1744798094.4704452,"logger":"http.acme_client","msg":"trying to solve challenge","identifier":"forum.twogeeksonecup.wtf","challenge_type":"tls-alpn-01","ca":"https://acme-v02.api.letsencrypt.org/directory"}
> Apr 16 12:08:15 raspberrypi caddy[37133]: {"level":"error","ts":1744798095.4341996,"logger":"http.acme_client","msg":"challenge failed","identifier":"forum.twogeeksonecup.wtf","challenge_type":"tls-alpn-01","status_code":403,"problem_type":"urn:ietf:params:acme:error:unauthorized","error":"Cannot negotiate ALPN protocol \"acme-tls/1\" for tls-alpn-01 challenge"}
> Apr 16 12:08:15 raspberrypi caddy[37133]: {"level":"error","ts":1744798095.4342725,"logger":"http.acme_client","msg":"validating authorization","identifier":"forum.twogeeksonecup.wtf","error":"authorization failed: HTTP 403 urn:ietf:params:acme:error:unauthorized - Cannot negotiate ALPN protocol \"acme-tls/1\" for tls-alpn-01 challenge","order":"https://acme-v02.api.letsencrypt.org/acme/order/2344428037/374726086037","at>
> Apr 16 12:08:16 raspberrypi caddy[37133]: {"level":"info","ts":1744798096.898213,"logger":"http.acme_client","msg":"trying to solve challenge","identifier":"forum.twogeeksonecup.wtf","challenge_type":"http-01","ca":"https://acme-v02.api.letsencrypt.org/directory"}
> Apr 16 12:08:18 raspberrypi caddy[37133]: {"level":"error","ts":1744798098.2031167,"logger":"http.acme_client","msg":"challenge failed","identifier":"forum.twogeeksonecup.wtf","challenge_type":"http-01","status_code":403,"problem_type":"urn:ietf:params:acme:error:unauthorized","error":"2602:fd3f:1:ff02::4b: Invalid response from http://forum.twogeeksonecup.wtf/.well-known/acme-challenge/48mWC6M15R0qp691YyK6zHKDeiVn1MpK42>
> Apr 16 12:08:18 raspberrypi caddy[37133]: {"level":"error","ts":1744798098.203184,"logger":"http.acme_client","msg":"validating authorization","identifier":"forum.twogeeksonecup.wtf","error":"authorization failed: HTTP 403 urn:ietf:params:acme:error:unauthorized - 2602:fd3f:1:ff02::4b: Invalid response from http://forum.twogeeksonecup.wtf/.well-known/acme-challenge/48mWC6M15R0qp691YyK6zHKDeiVn1MpK42H5RDXWlqs: 404","order>
> Apr 16 12:08:19 raspberrypi caddy[37133]: {"level":"error","ts":1744798099.3681986,"logger":"tls.obtain","msg":"could not get certificate from issuer","identifier":"forum.twogeeksonecup.wtf","issuer":"acme-v02.api.letsencrypt.org-directory","error":"HTTP 429 urn:ietf:params:acme:error:rateLimited - too many failed authorizations (5) for \"forum.twogeeksonecup.wtf\" in the last 1h0m0s, retry after 2025-04-16 10:16:51 UTC:>
> Apr 16 12:08:19 raspberrypi caddy[37133]: {"level":"warn","ts":1744798099.3685613,"logger":"http","msg":"missing email address for ZeroSSL; it is strongly recommended to set one for next time"}
> Apr 16 12:08:19 raspberrypi caddy[37133]: {"level":"error","ts":1744798099.5645368,"logger":"tls.obtain","msg":"could not get certificate from issuer","identifier":"forum.twogeeksonecup.wtf","issuer":"acme.zerossl.com-v2-DV90","error":"account pre-registration callback: failed getting EAB credentials: HTTP 422: caddy_legacy_user_removed (code 2977)"}
> Apr 16 12:08:19 raspberrypi caddy[37133]: {"level":"error","ts":1744798099.5646415,"logger":"tls.obtain","msg":"will retry","error":"[forum.twogeeksonecup.wtf] Obtain: account pre-registration callback: failed getting EAB credentials: HTTP 422: caddy_legacy_user_removed (code 2977)","attempt":1,"retrying_in":60,"elapsed":5.875216803,"max_duration":2592000}
> ~
> ~
> ~
> ~

3. Caddy version:

2.6.2

4. How I installed and ran Caddy:

I followed the guide mentioned above:

I received error-messages when starting caddy so I adjusted the caddyfile and added a “*” between root and path and also removed the author’s “gzip” line via #.

a. System environment:

Raspberry 5, latest Raspberry OS

b. Command:

I followed the tutorial and used the commands mentions there (see 4.)

d. My complete Caddy config:

> # The Caddyfile is an easy way to configure your Caddy web server.
> #
> # Unless the file starts with a global options block, the first
> # uncommented line is always the address of your site.
> #
> # To use your own domain name (with automatic HTTPS), first make
> # sure your domain's A/AAAA DNS records are properly pointed to
> # this machine's public IP, then replace ":80" below with your
> # domain name.
> 
> forum.twogeeksonecup.wtf {
> 	# Set this path to your site's directory.
> 	root * /var/www/html
> 	# gzip
> 	# 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

5. Links to relevant resources:

I followed this guide:

Thanks in advance!!
Dan

forum.twogeeksonecup.wtf resolves to a private IP, so Caddy can’t obtain a certificate for it.

You can either:

  • Disable HTTPS by changing forum.twogeeksonecup.wtf to http://forum.twogeeksonecup.wtf in your configuration
  • Make forum.twogeeksonecup.wtf publicly reachable on the Internet
  • Use the DNS-01 challenge to obtain the certificate

You could also:

  • Use tls internal to get a certificate that’s trusted only within your local environment
  • Provide a certificate manually using the tls directive

Aahh.. so I did something wrong when opening the ports 80 and 443 on my router?
In case this is because of my router / ISP would a Cloudflare tunnel be an option?

Thanks .. these are my very first steps in this strange new world of networking..

It was resolving to a 192.168.x.x address, which isn’t routable on the Internet.