Php-fastcgi only serving .php files or wildcard possible

To further explain, it’s a good idea to look at the expanded form of the php_fastcgi directive:

So basically:

  • The first chunk deals with redirecting requests where the path is a directory on disk which contains an index.php file. This also does nothing if the path already ends with a /. So for example it would redirect the request to path /foo to /foo/ (appending a /, to canonicalize the path to the directory), if /foo/index.php exists on disk.

  • The next chunk deals with doing path rewrites depending on whether a matching file exists on disk, and has the side-effect of remembering the part of the path after .php if the path included .php in it (this is important for the environment variables sent to your php-fpm server, so it works properly).

    • First it checks if {path} is a file that exists on disk. If so, it rewrites to that path. This essentially just short circuits the rest, and makes sure that requests to files that do exist on disk don’t get otherwise rewritten (see next steps below). So if you have a /js/app.js file on disk, then it will keep that path the same.
    • Second, it checks if {path}/index.php is a file that exists on disk. If so, it rewrites to that path. So for requests to a directory like /foo/ then it’ll look for /foo//index.php, normalize that to /foo/index.php, and rewrite to that if it exists. This is sometimes useful if you’re running a PHP app inside of another.
    • Lastly, it’ll rewrite to index.php, if that exists (it almost always should for modern PHP apps). This allows your PHP app to handle any request for paths that don’t map to files on disk, by using index.php as the entrypoint.
  • Then finally, the last chunk of config is what actually proxies the request to your php-fpm service to actually run your PHP code. It only proxies requests to paths that end with .php, so any file that isn’t a PHP file, and that does exist on disk, will not be handled by this and will fall though.

The php_fastcgi directive is not enough on its own, it should be paired with file_server to allow Caddy to serve your static files (JS, CSS, images, etc) which weren’t otherwise handled by the logic in php_fastcgi and fell through.

So to answer your questions, yes, that’s all working as intended.

  • If you make a request to /api, then it will be sent through your index.php, Laravel’s entrypoint, and go through your configured routes in Laravel. If you do have a defined route to handle /api, then Laravel will probably respond with a 200, and Caddy will proxy that back to the client.
  • A request to /test.php, when that file doesn’t exist, will get rewritten to index.php, and hit your Laravel entrypoint just the same. If you have no route in Laravel to handle that path, then Laravel will probably return a 404. If /test.php did exist though, then Caddy would ask php-fpm to run that script. It wouldn’t reach Laravel probably (unless you made it look like the contents of index.php)
  • Caddy will handle responding to any static file requests, and those won’t reach php-fpm and Laravel.
5 Likes