You can get around this some creative use of rewrite.
The following untested Caddyfile should achieve what you’re looking for:
0.0.0.0
root /srv/build
log / stdout
proxy /proxy my_node_service {
without /proxy
}
rewrite {
to {path} {path}/ /proxy{path}
}
It will try a file, if possible, then a folder, then it will pass the request to /proxy, but it won’t send /proxy upstream (to avoid confusing your backend node service).
So the rewrite happens after path matching for static files but before path matching for proxy?
Can you please clarify what your rewrite directive is supposed to do? The docs don’t show rewrite taking 3 args like that and Caddy complains with
Parse error: Wrong argument count or unexpected line ending after '{path}'
. I did try it with rewrite {path} /proxy/{path} but only the home page would load. All other pages Caddy returned a 404 rather than proxying to my backend. I also tried moving the rewrite directive above the proxy directive (does that matter?).
Now by way of explanation: there is an implicit base path of / after the rewrite directive but before the block. That means that all requests will be affected by this rewrite.
The to subdirective specifies, in order, which resources Caddy should attempt to serve. Firstly, we try {path}, which will resolve to a file if one exists, or move on if not. Next is {path}/, which will try a folder, if one exists. Lastly, we send it to /proxy{path} - which will treat a request for /foo (as an example) as a request for /proxy/foo.
Since anything at /proxy is being proxied to your node path, Caddy will always stop rewriting at this point (because it can always try this resource). In our proxy directive block, we use without to subtract /proxy from the path heading upstream, so that our node instance will receive the request for /foo instead of /proxy/foo (which will obviously not behave unless you’re expecting it).