2

Directives in an Caddyfile can have "matchers" that limit them to specific requests. This lets Caddy 2 serve different content for different paths, but what happens when multiple directives match the same request?

If I want to serve a mostly-static website using Caddy 2, but forward an /api/ area to some Node.js process, my Caddyfile might look like this:

fake-example.edge.app {
  root * /var/www/example
  reverse_proxy /api/* localhost:9000
  file_server *
}

A request to /api/user would match both the file_server * and reverse_proxy /api/* matchers, so it's not clear whether the request will go to the filesystem or the Node.js process.

I couldn't find anything in the Caddy 2 documentation that describes what should happen. In my own testing, the results seem to depend on the order the directives appear in the file, with earlier entries "winning". What is supposed to happen? If it's "undefined behavior", is there a better way to write this file to avoid the ambiguity?

Gerald Schneider
  • 19,757
  • 8
  • 52
  • 79

2 Answers2

2

In my understanding and experience reverse_proxy takes precedence because directives have a default implicit order: https://caddyserver.com/docs/caddyfile/directives#directive-order .

To force a different order you have at least 3 options:

  1. use a route:
    route /api/* {
      file_server
      reverse_proxy localhost:9000
    }
  1. change the default order with the order global option
  2. use handle with file_server before reverse_proxy
pic
  • 136
  • 3
1

From my understanding and experience, more specific is taken into consideration over more generic.

For instance in your case, anything matching /API/ should be forwarded to node, and anything else forwarded to the normal webserver.

At any rate, as long as /api/ isn't an actual folder on the website, requests hitting the website won't matter

Also see: https://caddyserver.com/docs/caddyfile/directives/root

unixandria
  • 171
  • 11