V2: File Server Subdirectory with Listings

How can I serve a sub directory with listings (i.e. browse enabled) while serving unlisted files at the root level in Caddy v2?

See the config I came up below. This just ends up redirecting me to the second server (:8811) when browsing to /public. Another approach I tried was to use the uri directive inside the file_server directive, but this (perhaps obviously) is not possible as uri can’t be used as a sub-directive in that context.

:8811/public/* {
    uri strip_prefix /public

    file_server browse {
        root /srv/public_files
    }
}

:8811 {
    @not_public {
        not path /public/*
    }

    file_server @not_public {
        root /srv/http
    }
}

Since this is more of a general question I’ll skip detailing my exact environment but I am running the official docker image (caddy/caddy:2.0.0-rc.3-alpine).

For now I came up with a workaround:

:8811 {
    @not_public {
        not path /public/*
    }

    file_server @not_public {
        root /srv/http
    }

    file_server /public/* browse {
        root /srv/public_files
    }
}

Combined with mounting the directory into the container like this: -v /srv/public_files:/srv/public_files/public:ro this works fine for me but is not all that pretty.

I think this is what you’re looking for:

:8811 {
    root * /srv/http

    handle /public/* {
        root * /srv/public_files
        uri strip_prefix /public
        file_server browse
    }

    file_server
}

If the path has the /public/ prefix, it’ll handle the request with a file browser, otherwise it’ll fall through to a regular file server.

We’re working on a feature for Caddy v2.1 that should make this a bit easier:

It would look a bit like this:

handle_path /public {
    root * /srv/public_files
    file_server browse
}
2 Likes

I agree, but is the handle block even necessary you think?

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