Encountering issues with serving static files from a subdirectory of the website root path

1. The problem I’m having:

I am trying to use Caddy as my web server. The website root is at /var/www/myurl.com, in which I have files such as index.html, etc.

All these files are served just fine. However, I also wish to serve other static files from the /var/www/myurl.com/assets directory, but these are not found by Caddy.

If I do a simple mv /var/www/myurlcom/assets/some_file.txt /var/www/myurl.com/, then that file would also be served.

I have tried tinkering with permissions (as suggested by Understanding Permissions for the Caddy server ) and adding a manual handle directive (as suggested by V2: File Server Subdirectory with Listings ), but none of these suggestions worked.

Based on the documentation for file_server, it seems that all should work fine without much further configuration needed, but I am clearly missing something.

2. Error messages and/or full log output:

No explicit error messages, but I am not seeing the intended behaviou as described in the above section.

3. Caddy version:

v2.11.4 h1:XKxkMTgNSizEvKG6QHue6cAsFOteU2qA61w2tKkCWi0=

4. How I installed and ran Caddy:

I installed Caddy as a .deb package (as per Install — Caddy Documentation ) and am running it as a system service (i.e. sudo systemctl start caddy). Perhaps worth mentioning that it also happens if I run Caddy as via the CLI, i.e. caddy run --config /etc/caddy/Caddyfile.

a. System environment:

Ubuntu 24.04.4 LTS x86_64. Not running as Docker container.

b. Command:

sudo systemctl start caddy 

… and after making changes to my Caddyfile, I run:

caddy reload --config /etc/caddy/Caddyfile

d. My complete Caddy config:

myurl.com {
	root /var/www/myurl.com
	file_server
}

(throughout this post, I have changed the actual domain name to myurl.com to stay anonymous)

When you have the file under assets/, how are you requesting the file? What’s the URL you’re using?

Hello Mohammed,

In the case of my example with /var/www/myurl.com/assets/some_file.txt, I request the file by going to Firefox and entering https://myurl.com/assets/some_file.txt.

PS. Thanks for creating this great project :slight_smile:

Enable debug level logs by adding this to the top of your Caddyfile

{
    debug
}

Then make a request and copy the log for he please

In the process of enabling the debug logs, I tried running Caddy as root, and the files were correctly served. So it’s definitely an issue with file permissions.

However, I would still like for the system service to work (where the caddy user owns the process).

I tried running the following commands from root:

chown -R www-data:www-data assets
chown -R caddy:caddy assets
chmod -R 644 assets

Even though I confirmed that all the files are correctly owned by with ls -l assets, every time I request the files from a web browser, it still doesn’t work.

Any ideas about what the issue could be?

The second line here invalidates the first line. You can’t have the same set of files owned by 2 different users/groups.

The caddy user, which is used by systemd, is a member of its own group as well as www-data. This means it should be able to access the files if they’re owned by either of them. Do you have selinux?

Ah, should perhaps have specified that I did not run all three lines at once :slight_smile: I ran a line, checked if the issue was fixed, and then ran the next.

And yes, I would agree, this is the output of ls -l:

-rw-r--r-- 1 www-data www-data  57529 Sep 24 13:26 some_file.txt
-rw-r--r-- 1 www-data www-data  57529 Sep 24 13:26 some_other_file.txt

And here is the verification that the systemctl service is running as the caddy user. The file /lib/systemd/system/caddy.servicecontains:

# caddy.service
#
# For using Caddy with a config file.
#
# Make sure the ExecStart and ExecReload commands are correct
# for your installation.
#
# See https://caddyserver.com/docs/install for instructions.
#
# WARNING: This service does not use the --resume flag, so if you
# use the API to make changes, they will be overwritten by the
# Caddyfile next time the service is restarted. If you intend to
# use Caddy's API to configure it, add the --resume flag to the
# `caddy run` command or use the caddy-api.service file instead.

[Unit]
Description=Caddy
Documentation=https://caddyserver.com/docs/
After=network.target network-online.target
Requires=network-online.target

[Service]
Type=notify
User=caddy
Group=caddy
ExecStart=/usr/bin/caddy run --environ --config /etc/caddy/Caddyfile
ExecReload=/usr/bin/caddy reload --config /etc/caddy/Caddyfile --force
TimeoutStopSec=5s
LimitNOFILE=1048576
PrivateTmp=true
ProtectSystem=full
AmbientCapabilities=CAP_NET_ADMIN CAP_NET_BIND_SERVICE

[Install]
WantedBy=multi-user.target

And confirming that caddy user is part of the www-data group:

>> getent group | grep caddy
www-data:x:33:caddy
caddy:x:988:

No, SELinux is disabled.

FWIW, I also tried removing the entire /var/www/myurl.com directory and starting from a clean slate, to assert that no lingering configuration, permission etc was causing trouble, but this didn’t work either.

Share the logs let us see what’s happening

Perhaps expected, it turns out that a lingering file permission was the cause of the issue. After reinstalling everything completely from scratch, it worked :slight_smile:

@Mohammed90, thanks a lot for your diligent support!