Need basic help on using Caddy

1. The problem I’m having:

Thank you for existing, please be gentle when I stumble. The formatting on this page is foreign to me. Also, I am not very familiar with networking,

My goal: Set up a Home Linux server with Immich and make it accessible over HTTPS outside my LAN by means of using Caddy.
But I am having difficulties understanding how to set up
Caddy for this purpose, or even basic use of Caddy.

The server OS is Kubuntu 24.04.3 LTS. No problems. The IMMICH installation is V2.5.5 (docker container). Accessible in LAN, no problems.

Caddy is version v2.10.2 (stable), installed using apt. The “Slanted” Caddy page is initially accessible in LAN (until I raplaced :80 with my domain). So far so good.

My external ip is XX.YYY.ZZ.141 (obfuscated). My router is a TP-Link M9 Plus. Behind the router are several machines. The server with Caddy has internal ip 10.0.0.107

First goal is to access the “Slanted” Caddy page from outside my LAN. Therefore, I changed /etc/caddy/Caddyfile to refer to my domain instead of just :80 (see below). Problems began here.

For my domain, I have added an “A” record immich.arnholm.org which is forwarded to XX.YYY.ZZ.141:28080

In the TP-Link M9 Plus app I have defined in “Port forwarding” an external port 28080 is routed to internal ip 10.0.0.107:80

This is probably where I messed up, but I can’t figure out how to otherwise select which machine in my LAN is supposed to handle the external request (previously I have used HTTP to route internally this way).

I have asked someone outside my LAN to try immich.arnholm.org
The error response seen on their side:

This site can’t provide a secure connection
XX.YYY.ZZ.141 sent an invalid response.
ERR_SSL_PROTOCOL_ERROR

2. Error messages and/or full log output:

I am providing the latest part, the log is very long

Feb 06 22:19:50 R8HOME caddy[1277]: {"level":"error","ts":1770412790.94333,"msg":"challenge failed","identifier":"immich.arnholm.org","challenge_type":"tls-alpn-01","problem":{"type":"urn:ietf:params:acme:error:tls","title":"","detail":"194.63.248.52: remote error: tls: no application protocol","instance":"","subproblems":null},"stacktrace":"github.com/mholt/acmez/v3.(*Client).pollAuthorization\n\tgithub.com/mholt/acmez/v3@v3.1.2/client.go:557\ngithub.com/mholt/acmez/v3.(*Client).solveChallenges\n\tgithub.com/mholt/acmez/v3@v3.1.2/client.go:378\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"}
Feb 06 22:19:50 R8HOME caddy[1277]: {"level":"error","ts":1770412790.943473,"msg":"validating authorization","identifier":"immich.arnholm.org","problem":{"type":"urn:ietf:params:acme:error:tls","title":"","detail":"194.63.248.52: remote error: tls: no application protocol","instance":"","subproblems":null},"order":"https://acme-staging-v02.api.letsencrypt.org/acme/order/264066113/31558294283","attempt":2,"max_attempts":3,"stacktrace":"github.com/mholt/acmez/v3.(*Client).ObtainCertificate\n\tgithub.com/mholt/acmez/v3@v3.1.2/client.go:152\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"}
Feb 06 22:19:50 R8HOME caddy[1277]: {"level":"error","ts":1770412790.9435966,"logger":"tls.obtain","msg":"could not get certificate from issuer","identifier":"immich.arnholm.org","issuer":"acme-v02.api.letsencrypt.org-directory","error":"HTTP 400 urn:ietf:params:acme:error:tls - 194.63.248.52: remote error: tls: no application protocol"}
Feb 06 22:19:50 R8HOME caddy[1277]: {"level":"error","ts":1770412790.9436421,"logger":"tls.obtain","msg":"will retry","error":"[immich.arnholm.org] Obtain: [immich.arnholm.org] solving challenge: immich.arnholm.org: [immich.arnholm.org] authorization failed: HTTP 400 urn:ietf:params:acme:error:tls - 194.63.248.52: remote error: tls: no application protocol (ca=https://acme-staging-v02.api.letsencrypt.org/directory)","attempt":3,"retrying_in":120,"elapsed":192.746588365,"max_duration":2592000}

3. Caddy version:

v2.10.2 h1:g/gTYjGMD0dec+UgMw8SnfmJ3I9+M2TdvoRL/Ovu6U8=

4. How I installed and ran Caddy:

sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl
curl -1sLf ‘https://dl.cloudsmith.io/public/caddy/stable/gpg.key’ | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf ‘https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt’ | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo chmod o+r /usr/share/keyrings/caddy-stable-archive-keyring.gpg
sudo chmod o+r /etc/apt/sources.list.d/caddy-stable.list
sudo apt update
sudo apt install caddy

a. System environment:

Distributor ID: Ubuntu
Description: Ubuntu 24.04.3 LTS
Release: 24.04
Codename: noble

b. Command:

systemctl status caddy
sudo nano /etc/caddy/Caddyfile

d. My complete Caddy config

immich.arnholm.org {

    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

}

There’s currently nothing listening on immich.arnholm.org:28080, so I’m guessing you’ve either disabled port forwarding on your router or turned off Caddy.

Either way, your setup as it stands won’t work.

By default, unless configured otherwise, Caddy tries to get a certificate using either the HTTP-01 or TLS-ALPN-01 challenge. You can read more about the different challenge types here:

The HTTP-01 challenge only works on port 80, and the TLS-ALPN-01 challenge works over TLS on port 443. Since you’re using port 28080 on your router, neither of these challenges will succeed. To make this work, you’ll either need to forward ports 80 and 443 (or just 443) to Caddy, or switch to the DNS-01 challenge instead.

For DNS-01, Caddy needs to be compiled with a module that supports your DNS provider.

It looks like you’re using custom DNS hosting, since I don’t recognize hyp.net:

$ dig +noall +answer NS arnholm.org
arnholm.org.		86400	IN	NS	ns1.hyp.net.
arnholm.org.		86400	IN	NS	ns2.hyp.net.
arnholm.org.		86400	IN	NS	ns3.hyp.net.

So you might have trouble finding an existing Caddy DNS module that supports it.

One workaround is to delegate _acme-challenge.immich.arnholm.org to a different DNS provider that does have a supported module. Or you could delegate _acme-challenge.arnholm.org and issue a wildcard certificate for *.arnholm.org. That’s what I do at home.

More on that approach here:

I am very grateful for your assistance. Thank you so much for replying to my newbie questions! My goal is to have a setup as simple as possible, i.e. use stable Caddy with a standard configuration.

I learned from your reply that my thinking about port forwarding and consequently my implementation of it was flawed. Right now the status is the server (internal IP 10.0.0.107) is running and Caddy is running as a service. I intend to keep it that way until this thread is concluded. The DNS record for immich.arnholm.org is unchanged (edit: now only the IP, no port), it points to the external IP of my router.

I did the following changes in my TP-Link mesh router since my first post:

  • port forwarding of port 28080 was removed
  • Added port forwarding of external port 443 → 10.0.0.107:443
  • Added port forwarding of external port 80 → 10.0.0.107:80

I have some difficulties trusting testing from within my LAN, but disabling WIFI on my mobile and testing via mobile browser over 4G seems to be successful! I can now see the “slanted” Caddy welcome page with apparently no security warnings. However, I am waiting for external testing by a friend before concluding on this.

If this is indeed the fix to make Caddy work (looks like it!), the next step is to change the Caddyfile to use reverse_proxy and access the already existing immich server running in a docker container on the same machine. I am hoping I will just need the following to make it work:

immich.arnholm.org {
reverse_proxy localhost:2283
}

I can report success!

The Caddy setup works allowing access with HTTPS now. I also enabled reverse proxy to my IMMICH server setup as indicated before, and that seems to work also.

Finally, I installed the Immich app on my phone and was able to access the server that way too. Very happy, goal achieved.

The main issue for me was understanding how port forwarding between home router and server running Caddy was supposed to work. But this was quickly sorted by the help received here. Many thanks!

1 Like