Caddy sometimes behind local proxy

1. The problem I’m having:

I would like to have a caddy configuration that can work automatically whether it’s behind a local proxy or not.

My reasons for doing this is that this proxy is a work-in-progress, and I sometimes need to take it out of the chain.

The proxy is on the same machine as caddy, has the proper TLS certs, and forwards all requests to caddy.

So the 2 scenarios that I have come up with are:
a) WAN — https —> Caddy
b) WAN — https —> proxy — http —> Caddy

Does this seem like a proper approach, or am I making a mistake?

2. Error messages and/or full log output:

n/a

3. Caddy version:

v2.11.2

4. How I installed and ran Caddy:

a. System environment:

debian trixie bare metal with provided systemd unit file

b. Command:

PASTE OVER THIS, BETWEEN THE ``` LINES.
Please use the preview pane to ensure it looks nice.

c. Service/unit/compose file:

PASTE OVER THIS, BETWEEN THE ``` LINES.
Please use the preview pane to ensure it looks nice.

d. My complete Caddy config:

(redirect_https_unless_local_proxy) {
    @not_local not remote_ip 127.0.0.0/8 ::1
    redir @not_local https://{host}{uri} permanent
}

http://example.com {
    import redirect_https_unless_local_proxy
    respond 200
}

https://example.com {
    respond 200
}

5. Links to relevant resources:

This can work but I would probably avoid making port 80 do double duty.

A cleaner setup is usually:

  • Caddy direct path: public :443
  • local proxy path, proxy forwards to a separate local-only HTTP listener, e.g. 127.0.0.1:8080

That avoids needing to infer whether a request is direct HTTP or proxy-forwarded HTTP from the source IP alone.

For example, something like:

example.com {
    respond 200
}

http://example.com:8080 {
    bind 127.0.0.1
    respond 200
}

Then the local proxy forwards to http://127.0.0.1:8080.

If you need Caddy or upstream apps to know the real client IP / original scheme from the local proxy, configure trusted_proxies for loopback and make sure the proxy sends the usual X-Forwarded-* headers.

Your current approach is not fundamentally wrong but I would keep the proxy-to-Caddy path on a distinct local listener rather than mixing it in with with the public HTTP redirect path.

I have some hosts I want to continue to serve on :80 from my LAN.
For what it’s worth, there is no direct route from WAN:80 to caddy.

This is to cover the 2 scenarios of reaching public sites via WAN:443.