Serving files from different paths

Hi,

I am trying to serve files from multiple places on the server’s filesystem, but I just can’t seem to get it working.

Here is the host config:

https://test.theunimatrix.com {
        respond /hello "Hello, world!" 200

        header Content-Type text/html
        respond /bye <<HTML
                <html>
                        <head><title>Goodbye</title></head>
                        <body>Goodbye Cruel World</body>
                </html>
                HTML 200

        root Files /home/shared/Files
        root Database/* /home/mdiehl/Development/Buckets/Databases/

        file_server browse
}

As you can see, I’m testing a lot of things…

What I want to do is serve Files and Database from different locations. But when I browse to the URL, I just get a blank screen.

What am I missing?

Mike.

The handle directive can be used to match a request path. So if the path is /Database/*, then you can set a handle directive to point to the root. And if you want to get some kind of error instead of a blank screen, you could add a respond directive.

It would look like:

    handle /Files/* {
        root * /home/shared/Files
        file_server browse
    }

    handle /Database/* {
        root * /home/mdiehl/Development/Buckets/Databases
        file_server browse
    }

If you’re trying to strip the prefix, you could use the handle_path directive instead.

Hi, and thanks for looking at this.

I adjusted some paths, but based on your reply, I came up with this:

https://test.theunimatrix.com {
respond /hello “Hello, world!” 200

    header Content-Type text/html
    respond /bye <<HTML
            <html>
                    <head><title>Goodbye</title></head>
                    <body>Goodbye Cruel World</body>
            </html>
            HTML 200

    handle /Files/* {
            root * /home/mdiehl/Development/Caddy/www
            file_server browse
    }

    handle /Database/* {
            root * /home/mdiehl/Development/Buckets/Databases
            file_server browse
    }


    file_server browse

}

But it’s still only giving me a blank screen when I point my browser at:

https://test.theunimatrix.com/Files/

Even though there is a file at that path:

$ ls -la /home/mdiehl/Development/Caddy/www
total 12
drwxrwxr-x 2 mdiehl mdiehl 4096 Jan 10 15:25 .
drwxrwxr-x 4 mdiehl mdiehl 4096 Mar 6 21:42 …
-rw-rw-r-- 1 mdiehl mdiehl 15 Jan 10 15:25 test.txt

How is Caddy installed, and how are you running it? If it’s a Docker compose.yaml, I need to see it.

I downloaded the stand-alone binary. I eventually want to move to docker, but I’m not there yet.

I’ve moved all of the other sites to my “production” caddy server. So, I’ve been able to reduce this development server to this config:

https://test.theunimatrix.com {

respond /bye <<HTML
        <html>
                <head><title>Goodbye</title></head>
                <body>Goodbye Cruel World</body>
        </html>
        HTML 200

handle /Files/* {
        root * /home/mdiehl/Development/Caddy/www
        file_server browse
}

handle /Database/* {
        root * /home/mdiehl/Development/Buckets/Databases
        file_server browse
}


file_server browse

}

But this doesn’t work. I do note that if I point my browser to: https://test.theunimatrix.com/ I get a file directory of the current directory, which is “progress.”

Any ideas?
Mike.

The systemd unit file shipped with Caddy package has security hardening rules that prevent it from accessing anything under /home amongst others. Move your directories to be under /srv.

1 Like

To add on to @Mohammed90’s comment, Podman is an alternative to Docker. It is largely the same in regards to CLI commands and general operations, but Podman easily allows systemd integration and can utilize the /home directory, at least in rootless mode.

I used Docker for a few years and then moved to Podman for a few reasons, but systemd integration was a big factor for me.

This is all good to know, but I’m not using docker or systemd to start Caddy… yet.

I’m starting it with caddy run in the same directory as my Caddyfile.

I’ve changed my Caddyfile to point to /tmp and /etc instead of directories under /home, and I get the same results.

I just get a blank screen, but the Firefox Developer’s Tools tells me that I’m getting a 404.

I don’t see any indication in the console that’s running caddy, and I don’t know where the actual logs are. I’ve looked in /var/log/caddy, but don’t find any files.

So, I turned logging on and received:

2025/03/21 18:35:42.124 INFO http.log.access.log0 handled request {“request”: {“remote_ip”: “192.168.1.15”, “remote_port”: “39139”, “client_ip”: “192.168.1.15”, “proto”: “HTTP/3.0”, “method”: “GET”, “host”: “test.theunimatrix.com”, “uri”: “/Database/”, “headers”: {“Sec-Fetch-User”: [“?1”], “Alt-Used”: [“test.theunimatrix.com”], “Accept”: [“text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/png,image/svg+xml,/;q=0.8”], “Sec-Fetch-Dest”: [“document”], “Upgrade-Insecure-Requests”: [“1”], “Sec-Gpc”: [“1”], “Accept-Encoding”: [“gzip, deflate, br, zstd”], “Cookie”: [“REDACTED”], “User-Agent”: [“Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:131.0) Gecko/20100101 Firefox/131.0”], “Sec-Fetch-Mode”: [“navigate”], “Accept-Language”: [“en-US,en;q=0.5”], “Sec-Fetch-Site”: [“none”], “Dnt”: [“1”], “Priority”: [“u=0, i”]}, “tls”: {“resumed”: false, “version”: 772, “cipher_suite”: 4865, “proto”: “h3”, “server_name”: “test.theunimatrix.com”}}, “bytes_read”: 0, “user_id”: “”, “duration”: 0.00009722, “size”: 0, “status”: 404, “resp_headers”: {“Server”: [“Caddy”], “Date”: [“Fri, 21 Mar 2025 18:35:42 GMT”]}}

But it doesn’t tell me where Caddy looked on the filesystem to fill this request.

What can I do?

TIA,
Mike.

Enable debug logs to see more details

I have enabled logs with:

https://test.theunimatrix.com {
log {
level DEBUG
format json
}

handle /Files/* {
        root * /tmp
        file_server browse
}

handle /Database/* {
        root * /etc
        file_server browse
}

file_server browse

}

But, when I visit https://test.theunimatrix.com/Database I don’t see in the logs where Caddy indicates where on the server’s filesystem it was looking in order handle this request for /Database.

Here is that log:

{
“level”: “info”,
“ts”: 1742590007.6336412,
“logger”: “http.log.access.log0”,
“msg”: “handled request”,
“request”: {
“remote_ip”: “192.168.1.15”,
“remote_port”: “35182”,
“client_ip”: “192.168.1.15”,
“proto”: “HTTP/3.0”,
“method”: “GET”,
“host”: “test.theunimatrix.com”,
“uri”: “/Database/”,
“headers”: {
“Upgrade-Insecure-Requests”: [
“1”
],
“Priority”: [
“u=0, i”
],
“Accept”: [
“text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/png,image/svg+xml,/;q=0.8”
],
“Alt-Used”: [
test.theunimatrix.com
],
“Cookie”: [
“REDACTED”
],
“Sec-Fetch-Mode”: [
“navigate”
],
“Sec-Gpc”: [
“1”
],
“Sec-Fetch-Dest”: [
“document”
],
“Dnt”: [
“1”
],
“Sec-Fetch-User”: [
“?1”
],
“User-Agent”: [
“Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:131.0) Gecko/20100101 Firefox/131.0”
],
“Sec-Fetch-Site”: [
“none”
],
“Accept-Language”: [
“en-US,en;q=0.5”
],
“Accept-Encoding”: [
“gzip, deflate, br, zstd”
]
},
“tls”: {
“resumed”: false,
“version”: 772,
“cipher_suite”: 4865,
“proto”: “h3”,
“server_name”: “test.theunimatrix.com
}
},
“bytes_read”: 0,
“user_id”: “”,
“duration”: 0.000104306,
“size”: 0,
“status”: 404,
“resp_headers”: {
“Server”: [
“Caddy”
],
“Date”: [
“Fri, 21 Mar 2025 20:46:47 GMT”
]
}
}

So, I don’t know how to debug this.

Mike.

You didn’t follow the instructions I shared in the link.

What @Mohammed90 wants you to do is add debug to the global options block, not the site block. Anyway, what I suspect is you’re not able to see the file server browse due to a misconfiguration, and you’re trying to see the ./Caddy/www folder’s contents within https://test.theunimatrix.com/Files/, and ./Buckets/Databases in https://test.theunimatrix.com/Buckets/.

If that’s the configuration you need, this is how it should look.

https://test.theunimatrix.com {

	respond /bye <<HTML
		<html>
		<head><title>Goodbye</title></head>
		<body>Goodbye Cruel World</body>
		</html>
		HTML 200

	handle /Files* {
		root * /home/mdiehl/Development/Caddy
		file_server browse
	}

	handle /Database* {
		root * /home/mdiehl/Development/Buckets
		file_server browse
	}


	file_server browse

}

1 Like