Caddyfile and v2

Hi again,

I’m now running beta v13 and trying to have this setup implemented.

Quick recap, at the moment I have this:

gon.cat {
     strip_prefix /talks/* /talks/
     root /talks/* /var/www/talks/
     root * /var/www/home
     file_server
}

https://gon.cat works serving a simple static page and it’s served properly with the contents of /var/www/home. Then at /var/www/talks/vim I have and index.html file with the same permissions as the other sites served:

gonzalo@do2:~$ ls -l /var/www/talks/vim/index.html
-rw-r--r-- 1 gonzalo staff 14631 Jun  1  2019 /var/www/talks/vim/index.html

But I’m not able to serve /var/www/talks/vim/index.html at https://gon.cat/talks/vim, got a 404.

I tried removing the strip_prefix line, also adding slashes doing all the possible combinations without luck.

Thanks!

Ah… duh, this is because the adapted JSON contains:

"routes": [
	{
		"handle": [
			{
				"handler": "vars",
				"root": "/var/www/talks/"
			}
		],
		"match": [
			{
				"path": [
					"/talks/*"
				]
			}
		]
	},
	{
		"handle": [
			{
				"handler": "vars",
				"root": "/var/www/home"
			}
		]
	},
	...

which is normally what you’d want (the more specific handler goes first) but in this case, they need to be mutually exclusive. The second overwrites the first.

One way to solve this would be to structure your Caddyfile more like nginx config’s location blocks:

gon.cat

handle /talks/* {
    strip_prefix /talks/
    root /var/www/talks
}
handle {
    root /var/www/home
}
file_server

Another way would be for us/me to make the root directive mutually exclusive from all other root directive (kind of like handle and rewrite are).

Another way would be to define a matcher that makes them mutually exclusive yourself (i.e. “not /talks/” instead of catch-all).

Another way would be to define multiple sites:

gon.cat {
    root /var/www/home
    file_server
}

gon.cat/talks/* {
    root /var/www/talks
    strip_prefix /talks/
    file_server
}
1 Like

Thanks @matt!

This make the trick:

gon.cat {
    handle /talks/* {
        strip_prefix /talks/* /talks/
        root * /var/www/talks
    }
    handle {
        root * /var/www/home
    }
    file_server
} 

I had to add extra args to the strip_prefix and root directives but now it’s working \o/

1 Like

Oh. yeah, I forgot about that (the matcher tokens). But you can use * in your case since handle already does the path filtering for you:

gon.cat {
    handle /talks/* {
        strip_prefix * /talks/
        root * /var/www/talks
    }
    handle {
        root * /var/www/home
    }
    file_server
} 

Tbh though I think the second example (two sites, as opposed to handle) looks a little cleaner, but that’s just my opinion. I think it’s just a matter of preference!

I just changed it for the sake of testing and also works:

gon.cat {
    root * /var/www/home
    file_server
}

gon.cat/talks/* {
    root * /var/www/talks
    strip_prefix * /talks/
    file_server
}

Thanks again! :partying_face:

1 Like

Awesome!

Just to make your life easier (or to give you more choices), I’ve just made root directives mutually exclusive: https://github.com/caddyserver/caddy/commit/490cd02f826b00e52b6503b61436b8c7444fc30e

So with that, your original Caddyfile should work:

root /talks/* /var/www/talks/
root * /var/www/home
1 Like

Grea to hear that! I just compiled and run latest v2 version ec56c257089f42ef88ec3a5ec818965c0fa5d57f and this conf:

gon.cat {
    strip_prefix * /talks/
    root /talks/* /var/www/talks
    root * /var/www/home
    file_server
}

But could not make it work. If you need the JSON conf let me know.