I’m pretty sure I tried this setup this morning, but it was broking both the admin and the redirection of links.
What I wrote is different than what you wrote here:
Do my mind trying it again? Also don’t forget to rename or delete the index.php
you added, to get it out of the way.
OK you’re right, either I had not tried this setup, or tried it slightly differently. Anyway, you’re suggestion works, without editing the index.php file.
So, if you want to set up Caddy 2 for Yourls, here’s the correct Caddyfile you need :
domain.com {
root * /var/www/yourls
@canonicalPath {
file {
try_files {path}/index.php
}
not {
path */
}
}
redir @canonicalPath {path}/ 308
# If the requested file does not exist, try index files
try_files {path} {path}/index.php yourls-loader.php
# Proxy PHP files to the FastCGI responder
@phpFiles {
path *.php
}
reverse_proxy @phpFiles unix//run/php/php7.4-fpm-caddy.sock {
transport fastcgi {
split .php
}
}
file_server
encode zstd gzip
}
Thanks for your help.
EDIT : There is a simpler solution, if you’re using Caddy v2 beta 20 and above. Here’s what you need :
domain.com {
root * /var/www/yourls
route {
try_files {path} {path}/index.php yourls-loader.php
php_fastcgi unix//run/php/php7.4-fpm-caddy.sock
}
file_server
encode zstd gzip
}
I was just thinking about this a bit more… I have another idea that might be much simpler, I’m curious if you could give it a shot real quick to verify.
route {
try_files {path} {path}/index.php yourls-loader.php
php_fastcgi unix//run/php/php7.4-fpm-caddy.sock
}
So, the route
directive defines a block that is guaranteed to be executed in the order the contents are listed. What I think should happen with this config is that this will effectively override the try_files
behaviour built into php_fastcgi
by defaulting to yourls-loader.php
instead of a non-existent index.php
.
If this works for you, we’ll likely add this sort of example to the documentation as it’s starting to seem like a common pattern.
This is because Glitch’s PHP uses a built-in server,
PHP behavior has priority over Caddy.
(If there is no file, the build-in server refers to index.php
or index.html
)
I should have done a Caddyfile investigation in another environment.
Nope…
Caddy does not start and I have this error :
Mar 23 15:59:19 liens caddy[10902]: reload: adapting config using caddyfile: parsing caddyfile tokens for 'route': /etc/caddy/Caddyfile:15 - Error during parsing: php_fastcgi directive returned something other than an HTTP route: caddyhttp.Subroute{Routes:caddyhttp.RouteList{caddyhttp.Route{Group:"", MatcherSetsRaw:caddyhttp.RawMatcherSets{caddy.ModuleMap{"file":json.RawMessage{0x7b, 0x22, 0x74, 0x72, 0x79, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x22, 0x3a, 0x5b, 0x22, 0x7b, 0x68, 0x74, 0x74, 0x70, 0x2e, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x75, 0x72, 0x69, 0x2e, 0x70, 0x61, 0x74, 0x68, 0x7d, 0x2f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x70, 0x68, 0x70, 0x22, 0x5d, 0x7d}, "not":json.RawMessage{0x7b, 0x22, 0x70, 0x61, 0x74, 0x68, 0x22, 0x3a, 0x5b, 0x22, 0x2a, 0x2f, 0x22, 0x5d, 0x7d}}}, HandlersRaw:[]json.RawMessage{json.RawMessage{0x7b, 0x22, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x22, 0x3a, 0x22, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2c, 0x22, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x22, 0x3a, 0x7b, 0x22, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x3a, 0x5b, 0x22, 0x7b, 0x68, 0x74, 0x74, 0x70, 0x2e, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x75, 0x72, 0x69, 0x2e, 0x70, 0x61, 0x74, 0x68, 0x7d, 0x2f, 0x22, 0x5d, 0x7d, 0x2c, 0x22, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x22, 0x3a, 0x33, 0x30, 0x38, 0x7d}}, Terminal:false, MatcherSets:caddyhttp.MatcherSets(nil), Handlers:[]caddyhttp.MiddlewareHandler(nil), middleware:[]caddyhttp.Middleware(nil)}, caddyhttp.Route{Group:"", MatcherSetsRaw:caddyhttp.RawMatcherSets{caddy.ModuleMap{"file":json.RawMessage{0x7b, 0x22, 0x74, 0x72, 0x79, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x22, 0x3a, 0x5b, 0x22, 0x7b, 0x68, 0x74, 0x74, 0x70, 0x2e, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x75, 0x72, 0x69, 0x2e, 0x70, 0x61, 0x74, 0x68, 0x7d, 0x22, 0x2c, 0x22, 0x7b, 0x68, 0x74, 0x74, 0x70, 0x2e, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x75, 0x72, 0x69, 0x2e, 0x70, 0x61, 0x74, 0x68, 0x7d, 0x2f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x70, 0x68, 0x70, 0x22, 0x2c, 0x22, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x70, 0x68, 0x70, 0x22, 0x5d, 0x7d}}}, HandlersRaw:[]json.RawMessage{json.RawMessage{0x7b, 0x22, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x22, 0x3a, 0x22, 0x72, 0x65, 0x77, 0x72, 0x69, 0x74, 0x65, 0x22, 0x2c, 0x22, 0x75, 0x72, 0x69, 0x22, 0x3a, 0x22, 0x7b, 0x68, 0x74, 0x74, 0x70, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x73, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x2e, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x7d, 0x22, 0x7d}}, Terminal:false, MatcherSets:caddyhttp.MatcherSets(nil), Handlers:[]caddyhttp.MiddlewareHandler(nil), middleware:[]caddyhttp.Middleware(nil)}, caddyhttp.Route{Group:"", MatcherSetsRaw:caddyhttp.RawMatcherSets{caddy.ModuleMap{"path":json.RawMessage{0x5b, 0x22, 0x2a, 0x2e, 0x70, 0x68, 0x70, 0x22, 0x5d}}}, HandlersRaw:[]json.RawMessage{json.RawMessage{0x7b, 0x22, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x22, 0x3a, 0x22, 0x72, 0x65, 0x76, 0x65, 0x72, 0x73, 0x65, 0x5f, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x22, 0x2c, 0x22, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x22, 0x3a, 0x7b, 0x22, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x22, 0x3a, 0x22, 0x66, 0x61, 0x73, 0x74, 0x63, 0x67, 0x69, 0x22, 0x2c, 0x22, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x22, 0x3a, 0x22, 0x2e, 0x70, 0x68, 0x70, 0x22, 0x7d, 0x2c, 0x22, 0x75, 0x70, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, 0x22, 0x3a, 0x5b, 0x7b, 0x22, 0x64, 0x69, 0x61, 0x6c, 0x22, 0x3a, 0x22, 0x75, 0x6e, 0x69, 0x78, 0x2f, 0x2f, 0x72, 0x75, 0x6e, 0x2f, 0x70, 0x68, 0x70, 0x2f, 0x70, 0x68, 0x70, 0x37, 0x2e, 0x34, 0x2d, 0x66, 0x70, 0x6d, 0x2d, 0x63, 0x61, 0x64, 0x64, 0x79, 0x2e, 0x73, 0x6f, 0x63, 0x6b, 0x22, 0x7d, 0x5d, 0x7d}}, Terminal:false, MatcherSets:caddyhttp.MatcherSets(nil), Handlers:[]caddyhttp.MiddlewareHandler(nil), middleware:[]caddyhttp.Middleware(nil)}}, Errors:(*caddyhttp.HTTPErrorConfig)(nil)} (only handler directives can be used in routes)
That’s a fun little bug…
Thanks for trying it!
To clarify what @matt is saying, the problem is that php_fastcgi
is a composite directive, it maps to a bunch of different matchers and handlers. The route
directive doesn’t seem to know how to handle these right now, because it doesn’t allow matchers inside of itself I think. So definitely a little bug in the Caddyfile.
OK, thanks for the explanations. I have restored the longer version for now.
@nicolinux @francislavoie Fixed that up and I confirmed that it worked (meaning, didn’t produce an error): httpcaddyfile: Allow php_fastcgi to be used in route directive · caddyserver/caddy@348cb79 · GitHub - can you please build from that commit and try again? I did not test it with your particular use case (I don’t have a PHP environment.)
If you test it in the next few hours and it doesn’t work, I can probably fix it before beta 19 goes out today.
Thanks for your patience and for trying various things! And thanks Francis for your help.
I’ll do you one better. You shouldn’t even need to build from source! You can grab one of the build artifacts from our CI pipeline for that commit: httpcaddyfile: Allow php_fastcgi to be used in route directive · caddyserver/caddy@348cb79 · GitHub
Later beta19 was released, but it had new bugs related to php. Do not update yet:
https://github.com/caddyserver/caddy/issues/3178
Yeah, sorry about that. Instead you can use fastcgi: Fix PATH_INFO (issue #3178) · caddyserver/caddy@235357a · GitHub which does have the fix.
I will rather wait for the next beta, my workflow depends on the GitHub releases and the artefacts are not working in the same way.
When the beta 20 is out, I will try and report though.
Please test it before then. I know that’s not super convenient but we’re also working hard to make sure the bug is fixed before we release it rather than after.
Sorry, I had no time to work more on this yesterday.
I installed the beta 20 this morning on a different server, and I have this error preventing it from starting :
Mar 25 07:47:43 voiretmanger caddy[8760]: run: loading initial config: loading new config: loading http app module: provision http: server srv0: setting up route handlers: route 3: loading handler modules: position 0: loading module 'subroute': provision http.handlers.subroute: setting up subroutes: route 8: loading handler modules: position 0: loading module 'reverse_proxy': provision http.handlers.reverse_proxy: loading transport: loading module 'fastcgi': decoding module config: http.reverse_proxy.transport.fastcgi: json: cannot unmarshal string into Go struct field Transport.split_path of type []string
Here’s the Caddyfile :
voiretmanger.fr {
root * /var/www/voiretmanger.fr
encode zstd gzip
php_fastcgi unix//run/php/php7.4-fpm-caddy.sock
file_server
import logs
# Redirect personnels
redir /a-propos/publicite /soutien
redir /archives/carte-des-restaurants /a-manger
header {
# enable HSTS
Strict-Transport-Security max-age=31536000;
# disable clients from sniffing the media type
X-Content-Type-Options nosniff
# keep referrer data off of HTTP connections
Referrer-Policy no-referrer-when-downgrade
}
request_header /wp-content Cache-Control "public, max-age=2592000, s-maxage=86400"
request_header /wp-includes Cache-Control "public, max-age=2592000, s-maxage=86400"
request_header favicon.ico Cache-Control "public, max-age=2592000, s-maxage=86400"
}
Should I open a Github bug report ? I see the error is linked to routing, so I was wondering if it was the same bug as before or a different one.
In the meantime, I’m revering back to beta 18.
Let me know if you need more informations.
I’m not able to reproduce that error with the config you gave. It adapts just fine for me.
Couple notes:
I’m not seeing that in your Caddyfile. Can you post your whole config? It’s likely the error is happening because of something you didn’t include.
You have a weird unicode character in there. 0x007f, right after .ico
. Strange.
Anyways, I don’t think favicon.ico
is valid here, I’m pretty sure you’ll need to add a slash in front /favicon.ico
so that Caddy detects that as a path matcher.
Edit: Reading the error again, I think Caddy is reading your config from the autosave.json
location instead of reading your current config. There was a change in how the split_path
option of the transport works, the error looks like it’s related to that option being configured as a string instead of an array of strings; makes me think it’s a stale JSON config.
Edit2: Yup the error is as I suspected, stale config. I took the adapted JSON, changed the split_path
option to a string instead of an array of strings, and I get this error:
$ ./caddy2_beta20_linux_amd64 validate --config conf-f7260.json
2020/03/25 07:56:09.319 INFO using provided configuration {"config_file": "conf-f7260.json", "config_adapter": ""}
2020/03/25 07:56:09.320 INFO http server is listening only on the HTTPS port but has no TLS connection policies; adding one to enable TLS {"server_name": "srv0", "https_port": 443}
2020/03/25 07:56:09.320 INFO http enabling automatic HTTP->HTTPS redirects {"server_name": "srv0"}
2020/03/25 03:56:09 [INFO][cache:0xc00057e000] Started certificate maintenance routine
2020/03/25 03:56:09 [INFO][cache:0xc00057e000] Stopped certificate maintenance routine
validate: loading http app module: provision http: server srv0: setting up route handlers: route 0: loading handler modules: position 0: loading module 'subroute': provision http.handlers.subroute: setting up subroutes: route 9: loading handler modules: position 0: loading module 'reverse_proxy': provision http.handlers.reverse_proxy: loading transport: loading module 'fastcgi': decoding module config: http.reverse_proxy.transport.fastcgi: json: cannot unmarshal string into Go struct field Transport.split_path of type []string
OK so it’s not the same issue, sorry for the mix-up. Maybe an admin could create a new post on the forum ?
Anyway, how should I handle this case ? Just delete the autosave.json
file ?
The log part was so simple, I did not even pasted here. But here you go :
(logs) {
log {
output file /var/log/caddy/access.log
}
}
And I will also change the request_header
commands. And thank you again for your help.
Yes. It was a one-time breaking change (sorry about that, but that’s how it goes in beta).
Definitely upgrade to beta 20, it has some important bug fixes.
No worry, it’s an easy fix. And indeed, it works fine now !
I will try to update the server with Yourls, to see if the simpler route solution works.
Thanks for your work by the way.
EDIT : great, the @francislavoie suggestion works fine with Caddy 2 b20. Thanks again.