Picocms settings

1. Caddy version (caddy version):

v2.4.6 h1:HGkGICFGvyrodcqOOclHKfvJC0qTU7vny/7FhYp9hNw=

2. How I run Caddy:

I don’t really understand this question. I only know of one way to use Caddy…

def install -y caddy
systemctl enable --now caddy

a. System environment:

Alma Linux 8

b. Command:

systemctl start caddy

c. Service/unit/compose file:


d. My complete Caddyfile or JSON config:

www.arcdigital.info {
	root * /var/www/html/pico
	php_fastcgi unix//run/php-fpm/www.sock

3. The problem I’m having:

This serves the HTML… but only the html. Any static files in nested paths elicit 404 errors.
So for example there will be files in these paths, that need serving:


4. Error messages and/or full log output:

Well there’s no error output… it just doesn’t serve the files.

5. What I already tried:

I read some things about adding a * to the path… but I couldn’t get that to work.
I saw some things on here about using @allowed but there’s nothing in the actual documentation about that and I couldn’t get that to work.
I saw some things about using handle but I couldn’t get a handle on that either.
I saw something on here about picocms but none of that worked. Also saw something about picocms for caddy on GitHub but none of that worked either.

Caddy is wonderfully simple… but the docs really don’t tell one very much at all, as far as I can tell, unless I just don’t understand them. For example file_server docs (file_server (Caddyfile directive) — Caddy Documentation) tell us nothing about how to serve multiple folders. Also says that it’s most often paired with root directive but gives almost no information about what that means or implies, nor how root deals with multiplicity either.

6. Links to relevant resources:

I don’t know if this helps but picocms has a .htaccess file, which can presumably be used as a source for understanding what needs to be done within Caddyfile (not that I’m capable of that).

cat /var/www/html/pico/.htaccess

RewriteEngine On
# May be required to access sub directories
#RewriteBase /

# Deny access to internal dirs and files by passing the URL to Pico
RewriteRule ^(config|content|vendor|CHANGELOG\.md|composer\.(json|lock|phar))(/|$) index.php [L]
RewriteRule (^\.|/\.)(?!well-known(/|$)) index.php [L]

# Enable URL rewriting
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ index.php [L]

<IfModule mod_env.c>
    # Let Pico know about available URL rewriting

Prevent file browsing

Options -Indexes -MultiViews

There are also others on Stackoverflow trying a similar thing for many months with no reply:

Yep, that’s what we were looking for – you could be for example running Caddy in a Docker container, or directly with caddy run etc. You’re running it as a systemd service :+1:

This would be the systemd service file, you can find the path to it by running systemctl status caddy. If you didn’t modify it, then I assume it’s the default as per Keep Caddy Running — Caddy Documentation

Well, a 404 would log an error. Check Caddy’s logs. You can find the recommended command to run to read your logs here:

Also, please make an example request with curl -v and show what that outputs; it might give some hints.

You configured it correctly – file_server will serve anything within the configured root.

The file paths are constructed by taking the root and appending the request path to it. So since your root is /var/www/html/pico, an HTTP request like /themes/default/css/app.css would look for a file on disk at /var/www/html/pico/themes/default/css/app.css.

All that said, it might be permission issue. Make sure the caddy user (which I assume Caddy is running as, if you’re using the default systemd config) has permissions to read those files. If the files are owned by www-data, make sure the caddy user is added to the www-data group.

I think this is because the URL’s are not quite as caddy expects or maybe it’s caddy that’s making them not quite the way pico expects. For example, in the source of the page generated by the CMS is this:

   <link rel="stylesheet" href="https://www.arcdigital.info:80/themes/default/css/style.css" type="text/css" />
    <link rel="stylesheet" href="https://www.arcdigital.info:80/themes/default/css/droidsans.css" type="text/css" />
    <link rel="stylesheet" href="https://www.arcdigital.info:80/themes/default/css/fontello.css" type="text/css" />

However it is the :80 that’s breaking things. If I take that URL and remove the :80, I can browse to it, e.g.


I don’t know what’s adding the :80?

Seems like PicoCMS has a misconfiguration. It definitely should not be putting port :80 on URLs.

So yeah, not an issue with Caddy, it’s a problem with your app.

1 Like

Actually, try upgrading to Caddy v2.5.0. I think there’s a change that will fix compatibility here:

I went looking in Pico’s codebase, and this is where it goes wrong:

Basically, Caddy previously didn’t set SERVER_PORT if the default HTTP or default HTTPS port was used to connect.

This from the picocms GitHub issues:

This is due to a misconfiguration of your webserver. Your webserver provides Pico with contradictory environmental information, making it virtually impossible to properly determine the base URL automatically. Check your webserver config, especially the environment variables passed to PHP, namely the SERVER_PORT and HTTPS environment variables (other related environment variables are shown here). Otherwise you’ll have to configure the base URL manually or write a plugin to properly resolve the conflicting environment variables.

Hmm, ok. I don’t know how to upgrade caddy on Alma Linux though :-/ Looks like the latest version available for Alma / CentOS is 2.4.6

Unfortunately v2.5.0 hasn’t been built on COPR yet (waiting for the COPR maintainers to do it) @caddy/caddy Copr

For now, you can replace your /usr/bin/caddy binary with a download from Download Caddy.

1 Like

Thanks for the amazingly quick reply and solution!

1 Like

Oddly while it works for the CSS, it’s not working for images. So this path works:


But this doesn’t, even though both have the same permissions.


What do you mean by “doesn’t work”? Please be specific. What error, exactly? What’s in your logs, as I wrote above?

Sorry, I’m not trying to be difficult :slight_smile: I’m just failing to understand…

The logs as per this command: “journalctl -u caddy --no-pager | less +G” don’t reveal anything, as far as I can tell. E.g. I tried the image URL again this morning but the last log entry is from last night.

By “it doesn’t work” I mean that when I browse (or curl) to the CSS file URL, the system realises that there is a static file there and it serves the static file. However when I browse (or curl) to the image file URL, the system doesn’t seem to recognise that there is a static file at that path and instead interprets the path as something to pass to PHP, so it just serves the index.php file. Which is a fallback, I guess.

Looking at the network tab, the GET request to the image is returning with no response data but with a 200 OK status.

I discovered something that may help…

This URL works (i.e. serves the static file successfully): https://www.arcdigital.info/themes/dimension/images/bg.jpg

If I move the ‘8.jpg’ file, from the preview folder, up a level – then it works. E.g. this works:
https://www.arcdigital.info/themes/dimension/images/8.jpg. So I don’t seem to be able to get at items in sub-folders oft he https://www.arcdigital.info/themes/dimension/images folder. Which made me think “permissions”.

The images folder has 0755 permissions, whereas its subfolders have 0644 permissions. If I change that to be 0755 then it works.

Is that as expected? Tx again.

1 Like

You can add this at the top of your Caddyfile to see more detail in your logs:


That’s php_fastcgi's default behaviour, yeah.

Sounds like PicoCMS isn’t written with modern PHP best-practices, i.e. using index.php for routing, and doesn’t look at PATH_INFO, and instead just serves your homepage with a 200 response. Modern apps would look at PATH_INFO and if it doesn’t recognize it as a known page, would write a 404 response.

In this case, you can configure the try_files option to fall back to throwing a 404 if the file isn’t found. See the docs: php_fastcgi (Caddyfile directive) — Caddy Documentation

Yep, that’s expected. The way directories work in Linux is that directories need the x (executable) permission to be navigable, and each parent directory must also have x as well. So if any parent dir doesn’t have x, then you can’t see the files.

1 Like

What permissions should PHP files have?

I think just readable by both the caddy user and whatever your PHP-FPM user is (probably www-data)

1 Like

On an extended theme of the same topic… how do I get PHP error logs?
Currently these are not being logged to caddy logs, nor to /var/log/php-fpm/error.log as far as I can tell.

You’ll need to configure php-fpm to write the error logs somewhere.

FYI @geoidesic COPR is updated with v2.5.0 (except openSUSE, needs extra attention)

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