caddy -version)?Caddy 0.10.4
Running caddy with php-fpm. I'm going to isolate some services, so there is no shared caddy root.
https://sub.example.com {
fastcgi / /srv/sub/php-fpm.sock php {
root /srv/sub/php-fpm-root
}
tls [email protected]
}
Via systemd. I'm going to put it into a jail, so don't worry about the root user and group (and don't try this at home). Here is my caddy.service:
[Unit]
Description=Caddy
After=network.target
[Service]
User=root
Group=root
Environment=CADDYPATH=/srv/caddy/.caddy
ExecStart=/usr/bin/caddy -log stdout -agree -conf /srv/caddy/caddyfile -ca https://acme-staging.api.letsencrypt.org/directory
ExecReload=/usr/bin/kill -USR1 $MAINPID
LimitNOFILE=1048576
LimitNPROC=64
[Install]
WantedBy=multi-user.target
curl -k "https://sub.example.com/index.php"
curl -k "https://sub.example.com"
Hello PHP world!
Hello PHP world!
Hello PHP world!
404 Not Found
Apparently caddy doesn't find the index.php file.
I can solve the problem by moving the root directive to the server block:
https://sub.example.com {
root /srv/sub/php-fpm-root
fastcgi / /srv/sub/php-fpm.sock php
tls [email protected]
}
$ curl -k "https://sub.example.com/index.php"
Hello PHP world!
$ curl -k "https://sub.example.com"
Hello PHP world!
It seems that caddy uses http.root instead of fastcgi.root to look for the fastcgi.index file. I'm not sure if this behaviour is intended. If it is, I suggest mentioning it in the docs.
Hi @casipw Thanks for the detailed issue. I can recreate this issue.
The code seems to be correctly assigning the root but it is not matching the index file as you have stated, however I'm not sure if we want this to happen as the docs suggest that in some instances the fastcgi server will be running on another server.
Perhaps @mholt could provide some clarity on what should happen in this situation, so either the code can be fixed or the documentation updated.
In the meantime I think you can do what you want by structuring your caddyfile in a differnt way.
If you explain what it is specifically you are trying to isolate we can make suggestions.
I'm heading out the door but I'll ping @abiosoft for his thoughts on it too!
@tobya I'm putting caddy and some services (one of it being a php-fpm instance) into Firejails. Caddy and each service have their own chroot-jail (like /srv/caddy, /srv/sub). I saw no need for a http.root directive, because that directory would conceptually belong to caddy and not to php-fpm. Some custom fastcgi services might not even need a root directory.
If I understand the code correctly, caddy tries to match an index file using http.root and fails because http.root is not defined. This matching is essential if there are multiple possible index filenames. However I wonder how it should work if Caddy and FastCGI were on different servers, as the docs suggest. (Also with my current http.root solution, caddy needs read access to /srv/sub.)
After sleeping a night to think about it, things seem clearer to me.
My PHP application does not need any static assets. (Otherwise I had seen the need for a http.root to put them there.)
If the URL ends with .php, caddy doesn't check for the existence of that file and thus doesn't need read access to any php files.
If the URL doesn't end with .php, caddy looks for an index file ("matching"). Therefor it needs read access to the directory with the php files.
Using http.root instead of fastcgi.root for the matching is the right choice. If caddy and php-fpm run on different servers (or jails, containers), one should mount the php directory (fastcgi.root on the php-fpm server) to the caddy server (mountpoint http.root on the caddy server).
I see three possible solutions here:
Docs: Mention in the docs that caddy needs access to the fastcgi root (via http.root) in order to match an index file.
Caddy code: Omit matching (and the need for read access to the fastcgi root) if there is exactly one fastcgi.index filename.
Admin: Use a rewrite rule to rewrite https://sub.example.com to https://sub.example.com/index.php. Now caddy doesn't need access to the php files any more.
https://sub.example.com {
rewrite {
r ^/$
to /index.php
}
fastcgi / /srv/sub/php-fpm.sock php {
root /srv/sub/php-fpm-root
}
tls [email protected]
}
This is a bit tricky, the root fileserver needs to be aware there are other places to look for files.
And I do not think it is limited to index files, any file that is not in http.root will give a 404, even if it is present in fastcgi.root.
Is it possible to define what fastcgi.root is really for then?
So it isn't possible to have different fastcgi root?
I tried to "proxy" from https://github.com/lucaslorentz/caddy-docker-proxy via fastcgi to php backend. So there is no http.root, just fastcgi.root
Caddy v2's redesigned middleware architecture solves this problem; URL rewriting including matching index files can be done outside of the reverse proxy (which is the module which serves fastcgi now). Since it's solved in v2 I'm going to close this.
Most helpful comment
Hi @casipw Thanks for the detailed issue. I can recreate this issue.
The code seems to be correctly assigning the root but it is not matching the index file as you have stated, however I'm not sure if we want this to happen as the docs suggest that in some instances the fastcgi server will be running on another server.
Perhaps @mholt could provide some clarity on what should happen in this situation, so either the code can be fixed or the documentation updated.
In the meantime I think you can do what you want by structuring your caddyfile in a differnt way.
If you explain what it is specifically you are trying to isolate we can make suggestions.