Location rules let a single proxy host route requests to different upstream targets based on the URL path. Instead of creating separate proxy hosts for each service, you define rules on one host:Documentation Index
Fetch the complete documentation index at: https://mintlify.com/fuomag9/caddy-proxy-manager/llms.txt
Use this file to discover all available pages before exploring further.
/api/* goes to your API server, /ws/* goes to a WebSocket server, and everything else goes to your frontend. This is modelled by the LocationRule type in proxy-hosts.ts and stored as locationRules on a ProxyHost.
How location rules work
When a request arrives at a proxy host, Caddy evaluates the location rules in order before falling back to the host’s default upstreams. EachLocationRule has a path pattern and a list of upstreams. If the request path matches the pattern, the request is forwarded to those upstreams — the default upstreams are not used for that request.
This makes it possible to use one domain as a gateway for multiple backend services:
/api/*→api-server:3000/ws/*→websocket-server:8080/*→frontend:3001(the host’s default upstream)
Creating location rules
Add more rules as needed
Repeat for each path you want to route separately. Order matters — see Rule priority below.
Path pattern syntax
Location rule paths use Caddy’s path matcher syntax. The most common patterns are:| Pattern | Matches |
|---|---|
/api/* | Any path starting with /api/ |
/ws/* | Any path starting with /ws/ |
/static/* | Any path starting with /static/ |
/health | The exact path /health only |
/v2/* | Any path starting with /v2/ |
* wildcard matches any sequence of path segments. Caddy path patterns are prefix-based by default when followed by /*.
Caddy path patterns are case-sensitive.
/API/* and /api/* are different patterns.Multiple upstreams per location
EachLocationRule accepts an array of upstream addresses in its upstreams field:
random). This is useful for scaling individual services independently — you can run three instances of your API server and one instance of your frontend, all behind the same domain.
Rule priority
Caddy evaluates location rules in the order they are listed. More specific patterns should come before less specific ones. If you have both/api/v2/* and /api/*, list /api/v2/* first. If /api/* appears first, it matches all /api/ paths including /api/v2/ ones, so the more specific rule is never reached.
The host’s default upstreams act as a final fallback — they handle any request that does not match any location rule.
Example: Microservices gateway
A single domainapp.example.com serves three separate services:
| Path | Service | Upstream |
|---|---|---|
/api/* | Backend REST API | backend:3000 |
/ws/* | WebSocket server | websocket:8080 |
/* | React frontend | frontend:3001 (default upstream) |
frontend:3001 as the host’s default upstream. The location rules capture /api/* and /ws/* requests; all other paths (including /, /about, /login) fall through to the frontend.
Enable allowWebsocket on the proxy host so that WebSocket upgrade headers are forwarded correctly to the /ws/* upstream.
Example: API versioning
Route two API versions to separate backend services while keeping the same domain:/api/v2/users go to new-api:4000. Requests to /api/v1/users go to legacy-api:3000. The /api/v2/* rule is listed first because it is more specific than /api/v1/* — in this case order does not actually matter since the prefixes do not overlap, but it is good practice.
This pattern allows a zero-downtime migration: run the old and new API versions in parallel, shift traffic gradually by updating your client applications, then remove the old rule when the migration is complete.