Caddy configuration example not working for multisite setup


(tpetry) #1

Hey, in the past months i migrated several setups to caddy resulting in much simpler configuration and less operational burden because of automatic https.But now i have a problem with a complex setup and multisite handling:

I copied the simple laravel example to process every url not pointing to static assets by PHP (which works perfectly fine):

example.com {
    root /var/www/html/public
    fastcgi / 127.0.0.1:9000 php
    rewrite {
        to {path} {path}/ /index.php?{query}
    }
}

To be able to handle multiple applications with one caddy instance i changed the code a little bit to work on a subfolder so i could run every application with a url prefix of the domain:

example.com/example {
    root /var/www/html/public
    fastcgi / 127.0.0.1:9000 php
    rewrite {
        to {path} {path}/ /index.php?{query}
    }
}

The problem is, as soon as caddy should look for example.com/example instead of example.com/ every url is served by php, the static assets are now longer accessible. But if the rewrite block is removed for testing the static assets are correctly accessible, but PHP will not work as the rule has been removed.

In which way has the laravel example to be modified that rewriting not available files are handled by php but it still works with subfolders?


(Matthew Fay) #2

You’ve changed the site label so it only matches URIs starting with /example, but if you haven’t actually shifted your site files to match the new paths relative to the web root, the rewriting will be failing. Clients will be requesting /example/path/to/file.txt, so Caddy will be looking in /var/www/html/public/example/path/to/file.txt, for example.

The fastest fix would be to move everything inside the webroot into an ./example folder.


(tpetry) #3

Is there some functionality to remove the /example prefix from the path only for the filesystem lookups? We’re using an enterprise software which we can’t control and are not allowed to change anything in the sourcecode or folder structure without losing our support contract.

Isn’t this in the end a bug in caddy for multisite setups? When a domain is set to example.com/example and the {path} placeholder is not able to find the filesystem information? It’s only working on the root folder and misses the edge cases of subpath setups.

Or is there some solution like the without property for the proxy module?


(Matthew Fay) #4

To clarify, the site label might be example.com/example, but the domain is still example.com, and the path still starts with /example.

This is almost the exact same as using a location /example inside of a virtual host for example.com in nginx. The path is the path, the domain is the domain - and the client is requesting /example/foo.bar from example.com, so if the request matches the site label, Caddy will look in the site root for ./example/foo.bar.

I don’t believe there is any way to configure Caddy to behave differently in this regard.


(Matthew Fay) #5

That said… you mention the without subdirective; you might be able to hack this behaviour in a roundabout way. It will (probably more than) double the resource load per request, but…

example.com/example {
  proxy / :2015 {
    without /example
  }
}

:2015 {
  internal
  root /var/www/html/public
  rewrite {
    to {path} {path}/ /index.php?{query}
  }
}

You’ll essentially be using the proxy’s without subdirective to get Caddy to talk to itself, stripping the prefix, on an internal-only port, which serves the actual site. You might need to look into http.filter to fix links coming back from the application, though, which will think it’s serving the site without /example… Fixing redirect headers currently isn’t possible either, I believe (pending a PR merge)… Could get complicated.

https://caddyserver.com/docs/http.filter

Lastly, if you can justify the business case, you could talk to Light Code Labs about purchasing some engineering support to suit Caddy to your requirements;

https://caddyserver.com/products/support

Otherwise, you can open a public feature request on the Github page, and a contributor might be able to take a look;