Caddy file server browse not working when root a specific directory

Here is my Caddyfile: {
        encode gzip
        file_server /files/* {
                root /files
        reverse_proxy /api/* localhost:7022
        file_server {
                root /srv

Here is my plan:

  1. When request URL is, Caddy can show me the index.html in /srv directory.
  2. When request URL is, Caddy can show me the file list in the /files directory in docker container.
  3. When request URL is, Caddy can pass this request to localhost:7022.

But when I request file server is not working, it gives me a 404. And I have check this directory in docker container, there have some files.

Here is my file tree at / in docker container:


Version: Caddy 2.4.6 in Docker.

P.S.: If you see the post on the, it also me.

Are you making a request to /files, or to /files/? You matcher is /files/* so only /files/ would match, of those two. You could change it to /files* which would match both, but then /filesssss would also match, FYI.

The way file_server works, Caddy will take the request path, and append it to the defined root, then look for files on disk at that location. So that means for a root of /files and request path of /files/example.txt it would look at /files/files/example.txt. You can see that /files is duplicated here. So you’d need to strip the /files prefix from the path before passing it to file_server for it to work. This can be done with handle_path, which has built-in path stripping logic.

I would write your config like this: {
	encode gzip

	handle /api* {
		reverse_proxy localhost:7022

	handle_path /files* {
		root * /files
		file_server browse

	handle {
		root * /srv
		file_server browse

Before you edited, you asked how to find your logs for docker-compose – just run docker-compose logs caddy


Very thank you! I changed my question to make it easier to understand. You totally answered my question and even show me the logic behind, and I am very clear now. Thank you very much again!


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