How do I set up multiple ports on localhost to a single backend?

1. The problem I’m having:

I’ve a backend that runs on port 9292 that exposes multiple paths (/foo/, /bar/ etc). I’m looking for a way to expose these individual top level directories as a subdomains in production (for example: foo.company.com, bar.compay.com) but for testing purposes on localhost, I’m looking to expose them on a separate port (for example: :9000 → :9292/foo/, :9001 → :9292/bar/). I’ve generated my Caddyfile and it seems to load and run without any issues but I’m unable to access the new ports as I get a 502.

2. Error messages and/or full log output:

On inspecting the logs, I see that Caddy is trying to hit port 80 which I haven’t specified anywhere.

2023/09/25 07:11:06.953 ERROR   http.log.error  dial tcp :80: connect: connection refused       {"request": {"remote_ip": "::1", "remote_port": "62238", "client_ip": "::1", "proto": "HTTP/1.1", "method": "GET", "host": "localhost:9002", "uri": "/", "headers": {"User-Agent": ["Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36"], "Accept-Language": ["en-US,en;q=0.9"], "Sec-Ch-Ua": ["\"Google Chrome\";v=\"117\", \"Not;A=Brand\";v=\"8\", \"Chromium\";v=\"117\""], "Dnt": ["1"], "Sec-Fetch-User": ["?1"], "Sec-Fetch-Site": ["none"], "Sec-Fetch-Mode": ["navigate"], "Accept-Encoding": ["gzip, deflate, br"], "Cookie": [], "Connection": ["keep-alive"], "Upgrade-Insecure-Requests": ["1"], "Accept": ["text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7"], "Sec-Ch-Ua-Mobile": ["?0"], "Sec-Ch-Ua-Platform": ["\"macOS\""], "Sec-Fetch-Dest": ["document"]}}, "duration": 0.000722583, "status": 502, "err_id": "08m25qxk4", "err_trace": "reverseproxy.statusError (reverseproxy.go:1246)"}

3. Caddy version:

v2.7.2 h1:QqThyoyUFAv1B7A2NMeaWlz7xmgKqU49PXBX08A+6xg=

4. How I installed and ran Caddy:

a. System environment:

macOS Ventura 13.3.1 (a), Apple M1 Pro, brew

b. Command:

caddy run

c. Service/unit/compose file:

NA

d. My complete Caddy config:

:9000  {
    reverse_proxy localhost:9292/foo/
}

:9001  {
    reverse_proxy localhost:9292/bar/
}

5. Links to relevant resources:

NA

You need to use the rewrite directive to change the request path. You can’t pass the request path directly to reverse_proxy, it only takes upstream addresses.

But keep in mind:

You’re probably better off using subdomains for each, like foo.localhost and bar.localhost.

Understood. Thank you so much for your help!