caddy passes on the source IP by default so it's even easier than that
photos.example.com {
reverse_proxy 127.0.0.1:8080
}
the immich documentation covers this as well as nginx, apache and traefik https://docs.immich.app/administration/reverse-proxy
Heh... I self-host Immich with Caddy, and it's more complex, really. Caddy runs in podman, there are firewall rules to allow traffic in and out and proper dependencies in systemd units and a readme that covers all that. Exactly the point OP is making.
All because we forced TLS on everyone instead of solving the JS injection problem in some other alternative way. Like... legal, maybe?