Reverse Proxy for Front and Backend Inconsistency

1. The problem I’m having:

I am hosting my react frontend with vite (port 5173) and my nodejs backend with express (port 5000). I am trying to use Caddy to reverse proxy a request to the proper server based on the request url. when i test this by making a request with

curl -X GET "heimerdinger.ecs-iot.com/api/"

it is horribly inconsistent. Yes, about half the time the request is forwarded to my backend API server. However, the other half of the time it returns HTML from my frontend vite server. In the below code blog for step 2 you can see one request where it returned the html and another where it got the response from my API endpoint.

2. Error messages and/or full log output:

(default) ➜  ~ curl -X GET "https://heimerdinger.ecs-iot.com/api/"
<!doctype html>
<html lang="en">
  <head>
    <script type="module">
import RefreshRuntime from "/@react-refresh"
RefreshRuntime.injectIntoGlobalHook(window)
window.$RefreshReg$ = () => {}
window.$RefreshSig$ = () => (type) => type
window.__vite_plugin_react_preamble_installed__ = true
</script>

    <script type="module" src="/@vite/client"></script>

    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Proxy Box</title>
    <script src="https://unpkg.com/@tailwindcss/browser@4"></script>
  </head>

  <body>
    <div id="app"></div>
    <script type="module" src="/src/main.tsx?t=1739473852618"></script>
  </body>
</html>
(default) ➜  ~ curl -X GET "https://heimerdinger.ecs-iot.com/api/"
API ENDPOINT!%

3. Caddy version:

v2.9.1

4. How I installed and ran Caddy:

I followed the Ubuntu installation instructions from the caddy website.

a. System environment:

Running an ubuntu 24.04 vm via Parallels.

b. Command:

caddy adapt
sudo caddy run

c. Service/unit/compose file:

d. My complete Caddy config:

heimerdinger.ecs-iot.com {
	handle /api* {
		reverse_proxy :5000
	}
	handle {
		basic_auth / {
			admin <password>
		}
		reverse_proxy :5173
	}
	tls {
		dns cloudflare <cloudflare-token>
	}
}

5. Links to relevant resources:

I should add - I spaced this when I posted yesterday, but I used xcaddy to install the cloudflare dns custom build from this repo GitHub - caddy-dns/cloudflare: Caddy module: dns.providers.cloudflare.

I have solved the issue. I unknowingly had multiple instances of Caddy running. When i killed all the old instances and restarted caddy it worked no issues.

2 Likes