File_server with two roots

1. The problem I’m having:

Want basically the static file_server where, if the file to serve is not in directory A, it will look to see if the file is in directory B. Similar to a union file system.

2. Error messages and/or full log output:

N/A

3. Caddy version:

v2.6.4 h1:2hwYqiRwk1tf3VruhMpLcYTg+11fCdr8S3jhNAdnPy8=

4. How I installed and ran Caddy:

a. System environment:

Ubuntu 22.04.2

b. Command:

/usr/local/bin/caddy run --environ --config /etc/caddy/Caddyfile

c. Service/unit/compose file:

N/A

d. My complete Caddy config:

The fragment of the configuration I imagine would look something like this:

handle /static/* {
	uri strip_prefix /static
	root * /directoryA
	file_server {
		fallback_root /directoryB
	}
}

5. Links to relevant resources:

N/A

Ah, you want try_files.

Trying try_files, but not having much luck. This is what I’m trying:

handle /static/* {
	uri strip_prefix /static
	root * /directoryA
	try_files {path} /directoryB/{path}
	file_server
}

It isn’t serving an files from /directoryB but is still from `/directoryA’.

That’s because you’ve set your root to /directoryA.

Instead, include the root in your various try_files paths, e.g. try_files {path} /directoryA/{path} /directoryB/{path}

Just keep in mind that anything in your site root could potentially be served by the server, so make sure there’s nothing in your root that you don’t want made public.

Okay, I think I’ve figured out where my difficulties lay. The problem is at least one of my directories lies outside the root. I’ve setup the following minimum example with the following files:

/test/Caddyfile
/test/root/root.html
/test/a/a.html
/test/b/b.html

And with Caddyfile:

http://localhost:8080 {
	root * /test/root
	try_files {path} /test/a/{path} /test/b/{path}
	file_server
}

So while http://localhost:8080/root.html works, http://localhost:8080/a.html and http://localhost:8080/b.html return 404.

By contrast, if I set it up as follows:

/test/Caddyfile
/test/root/root.html
/test/root/a/a.html
/test/root/b/b.html

with Caddyfile:

http://localhost:8080 {
root * /test/root
try_files {path} a/{path} b/{path}
file_server
}

All three URLs return their respective files.

With the way my project is setup, I’m really hoping I could use a configuration similar to the former though, where the try_files directories in question are outside the root.

It is possible, but it’s unwieldy:

example.com {
	root * /test/root
	@not-in-root not file {path}
	route @not-in-root {
		root * /test/a
		@not-in-a not file {path}
		route @not-in-a {
			root * /test/b
			file_server # will 404 at this point if not there
		}
		file_server
	}
	file_server
}

Brilliant. That did the trick. Thanks.

Just for completeness: going back to my original sample fragment, the config looks like this:

handle /static/* {
	uri strip_prefix /static
	root * /directoryA
	@not-in-a not file {path}
	route @not-in-a {
		root * /directoryB
		file_server
	}
	file_server
}

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.