You’re looking for try_files functionality. In Caddy, this comes as a request matcher, but there’s also a shortcut directive that is a combination of that matcher with a rewrite. See here:
In your case, since you also need to limit this to a certain path, you’ll need to use the expanded form (see the link) and add a path matcher.
Specifically, you want to try {path} first if it exists as a file on disk, otherwise fallback to your index.
I must say though, that this rewrite might not even be necessary in Caddy v2 because the php_fastcgi shortcut includes its own try_files behaviour! Did you try without the rewrite?
Thanks for you help Francis, I tried the following, but cannot get it to work. I’m obviously doidn gsomething wrong, but can’t quite see what… first time in Caddy 2
It does not work without this because it is like a seperate set of rewites and index.php under /panel. Of course the normal site with the index.php in the root works fine with the normal php_fastcg try_files` behaviour.
I did remove this, cleared my browser cache and tried running without, but it dos not work. The previous version of Caddy v1 did of course work and required it.
Ah right, sorry. Path matchers are exact match, meaning /panel will only match requests to /panel and not /panel/somethingelse. You need to use /panel* or /panel/* instead.
Also you’ll probably need to use try_files {path} /panel/index.php instead, because try_files has no knowledge of the path matcher.
However it seems to ignore or not match the /panel* part as now all pages go to the admin panel!
To recap the root of the site has an index.php which coupled with the try_files {path}/ /index.php?{query} work fine for the site but not the /panel admin subdirectory, which also has an index.php.
So I guess I really need to run: try_files /panel* {path} {path}/ /panel/index.php?{query}
when the path is /panel*
and try_files {path}/ /index.php?{query}
when it is not?
I don’t believe try_files accepts a matcher. The syntax is:
try_files <files...>
It’s not a true directive, in the sense that try_files does not directly configure its own specific module. Instead, it’s effectively a kind of common shorthand for a longer snippet of Caddyfile config:
The try_files directive is basically a shortcut for:
Except, use /panel/* instead of /panel (path matching is exact, as @francislavoie mentioned in the comment immediately following yours). And use {path} {path}/ /panel/index.php?{query} (which you said works) instead of {path} /index.php (which you said doesn’t).
Thanks Matthew for you help, do you mean like the code below? If so I’m getting a 404 error for ‘/panel’ links, or have I misunderstood what you were saying?
Sadly, as stated it errors:
This works for the admin panel (/panel) but all the other links also goto admin… try_files {path} {path}/ /panel/index.php?{query}
What’s your full Caddyfile? What’s the directory structure of the project you’re trying to serve? What are some example URLs that should work and which files should those URLs be rewritten to and serving?
Wrapping it in a handle is somewhat of a workaround to allow setting a matcher on a try_files directive which doesn’t otherwise allow a matcher. It’s closer to how the nginx config looks.
I needed the try_files {path}/ /index.php?&{query} otherwise I get domains on the non-panel part of the site like: http://domain.testindex.php/page
instead of http://domain.test/page
Not sure why I had to wrap it is a handle not /panel* , but it would 404 the admin panel if I did not?
How does this look to you? Am I missing anything else from the Caddyfile or should I structure it differently?
interestingly enough the latest Kirby 3 needs pretty much none of this, just the blocking stuff.
This isn’t right, you can’t have a full matcher in that position. The only valid values for inline matchers are a literal *, a path matcher starting with /, or a named matcher starting with @. To actually do that type of match, you’d need to do this:
Surprisingly, the Caddyfile parser doesn’t complain, but it’s because the handle directive parser just ignores the arguments given (it doesn’t consider not a matcher in that position, but just a regular argument).
So you’re saying that it works as expected now? Great!
I don’t find this too surprising, modern PHP frameworks/apps all work somewhat the same, and the php_fastcgi directive is crafted to work as effectively as possible for the modern approach by default.
But get an error on the ‘not /panel*’ line (43): validate: adapting config using caddyfile: Caddyfile:43 - Error during parsing: getting matcher module '/panel*': module not registered: http.matchers./panel*
Note sure what it means?
The way I tried in the previous post does validate and does work, but I’d like todo this properly if I can…