I'm currently testing Caddy 2 with Kirby CMS (a project I work for) to ensure that Kirby will support Caddy 2 right out of the gate.
It looks like the only issues are minor metadata issues in PHP's $_SERVER variable, which gets populated with env variables from the server.
caddy -version):v2.0.0-beta11
macOS High Sierra 10.13.6
PHP 7.4.1 via PHP-FPM
sudo caddy run -config /usr/local/etc/Caddyfile -adapter caddyfile
-
localhost:80 {
root * /Users/test/Desktop/test
tls off
encode gzip
file_server
php_fastcgi localhost:9000
}
$_SERVER in PHParray(42) {
["USER"]=>
string(4) "test"
["HOME"]=>
string(11) "/Users/test"
["DOCUMENT_URI"]=>
string(9) "index.php"
["QUERY_STRING"]=>
string(10) "view=panel"
["CONTENT_LENGTH"]=>
string(1) "0"
["HTTP_CONTENT_TYPE"]=>
string(16) "application/json"
["HTTP_PRAGMA"]=>
string(8) "no-cache"
["SCRIPT_NAME"]=>
string(9) "index.php"
["REMOTE_ADDR"]=>
string(8) "10.1.3.1"
["REMOTE_USER"]=>
string(0) ""
["HTTP_ACCEPT_LANGUAGE"]=>
string(35) "de-DE,de;q=0.9,en-US;q=0.8,en;q=0.7"
["HTTP_USER_AGENT"]=>
string(120) "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36"
["REMOTE_HOST"]=>
string(8) "10.1.3.1"
["AUTH_TYPE"]=>
string(0) ""
["HTTP_DNT"]=>
string(1) "1"
["HTTP_CACHE_CONTROL"]=>
string(8) "no-cache"
["SERVER_SOFTWARE"]=>
string(1) "/"
["SERVER_PORT"]=>
string(0) ""
["REMOTE_PORT"]=>
string(5) "56895"
["SERVER_PROTOCOL"]=>
string(8) "HTTP/1.1"
["PATH_INFO"]=>
string(0) ""
["HTTP_X_REQUESTED_WITH"]=>
string(14) "xmlhttprequest"
["HTTP_REFERER"]=>
string(27) "http://10.1.3.4/panel/login"
["HTTP_X_FORWARDED_FOR"]=>
string(8) "10.1.3.1"
["SCRIPT_FILENAME"]=>
string(34) "/Users/test/Desktop/test/index.php"
["REQUEST_METHOD"]=>
string(3) "GET"
["REMOTE_IDENT"]=>
string(0) ""
["HTTP_ACCEPT"]=>
string(3) "*/*"
["HTTP_COOKIE"]=>
string(153) "kirby_session=..."
["REQUEST_URI"]=>
string(22) "/api/system?view=panel"
["DOCUMENT_ROOT"]=>
string(25) "/Users/test/Desktop/test"
["HTTP_X_CSRF"]=>
string(64) "..."
["REQUEST_SCHEME"]=>
string(4) "http"
["HTTP_ACCEPT_ENCODING"]=>
string(13) "gzip, deflate"
["CONTENT_TYPE"]=>
string(16) "application/json"
["GATEWAY_INTERFACE"]=>
string(7) "CGI/1.1"
["HTTP_HOST"]=>
string(8) "10.1.3.4"
["SERVER_NAME"]=>
string(0) ""
["FCGI_ROLE"]=>
string(9) "RESPONDER"
["PHP_SELF"]=>
string(9) "index.php"
["REQUEST_TIME_FLOAT"]=>
float(1577561808.5411)
["REQUEST_TIME"]=>
int(1577561808)
}
The following env variables from the $_SERVER array are not populated correctly:
SERVER_SOFTWARE: "/" instead of something like "Caddy 2.0.0-beta11" or even just "Caddy"SERVER_NAME and SERVER_PORT: Completely empty, they should have been "localhost" and "80" respectively. If the Caddy config has multiple hosts configured as routes for that server, the passed value should preferably be the host and port of the current request.These four values are TODOs in the code right now. https://github.com/caddyserver/caddy/blob/82bebfab8a6528f24f23dac99ce5b11efab27761/modules/caddyhttp/reverseproxy/fastcgi/fastcgi.go#L41
Will use this issue to track progress. PRs welcome to speed this along, or I'll get to it eventually.
Thanks for testing Kirby against Caddy 2! Looking forward to making it work perfectly.
Alright. Good to see that it's already on your list. :)
@lukasbestle Luckily I had a minute while I was working on docs to fix these. If you try it at 5c8b502 they should be set better -- can you let me know?
Awesome, thanks for the fast fix. 馃憤
It's a lot better already and Kirby 3 works just fine with the new implementation.
One minor issue though: The SERVER_PORT is set to an empty string if there is no port in the request host. From other server implementations I'd expect it to be set to the port that actually received the request. So if it's 80 or 443 (the two cases where there doesn't need to be a port in the request host), SERVER_PORT should have the values "80" and "443" respectively.
Well, true...
If the Caddy config has multiple hosts configured as routes for that server, the passed value should preferably be the host and port of the current request.
And technically the Host header will often omit the port if it is a standard port. What does Kirby need this for?
So should this be the server's hard-coded host and port, then, and not from the Host header? Which is the source of truth?
The current implementation with both host and port coming from the request works fine for Kirby, it was just something that I noticed when looking at the raw values for testing.
It's probably an issue in some edge-cases where the application relies on the port always being set (which can be expected from other servers like Apache or nginx).
So should this be the server's hard-coded host and port, then, and not from the Host header? Which is the source of truth?
Definitely the current request! If I remember correctly, Apache uses the configured host in some setups and that's a huge pain in the butt for application devs like us (Kirby uses the SERVER_NAME and SERVER_PORT for automatic site URL generation and the URLs should always be in line with what the client sees on the outside, not with what is configured internally). So if we can't find a solution with the "best of both worlds", better keep it as it is now.
Idea:
SERVER_NAME should come from the Host header like in the current implementation (that works really great!).SERVER_PORT could however be the port on which the request was actually received by the server (if you have that value available in your code). This will always be based on the actual request (unlike a solution based on the fixed server configuration), but independent from whether the port is included in the Host header or not. So it will always provide a value.Could that work?
Hmm, I think it's trickier than that:
- The
SERVER_PORTcould however be the port on which the request was actually received by the server (if you have that value available in your code)
Technically yes, we can make this available to the request, but this being correct assumes that Caddy ("the server") is front-facing, which it may not be.
If that value isn't available, you could make empty values fall back automatically to either 80 or 443 depending on the protocol. If I didn't miss anything, this should actually cover all cases where the port is empty.
This is possible, with one nit -- as Caddy's HTTP and HTTPS ports are configurable, we'd actually have to use the server's configured HTTP / HTTPS ports depending on scheme.
I think at this point I'm going to leave the fix as-is, and if we get an actual use case where it's serious breakage, we can make another change on an actual need.
Thanks for your consideration and feedback! Please feel free to do continue any time as we get Caddy 2 ready to ship.
I see, that makes sense. Let's leave it like it is then to avoid an opinionated implementation. It's already working pretty well with the current setup. 馃憤
Is there a way to specify the port in the config for a site? I was testing out Caddy while building a site with a Laravel/PHP backend, and came across this specific issue when attempting to debug the code. My IDE (PHPStorm) could not accept the external Xdebug connection because this value was missing Cannot accept external Xdebug connection: Cannot evaluate expression '$_SERVER['SERVER_PORT']'. Switching my site back to NGINX for now, as debugging applications while working on them is extremely important.
Well, we'd need someone using _Caddy_ in order to help us implement it properly, so when you're willing to do that, let us know and open a new issue and we'll see what we can do.
@chewbakartik I think you can use the env subdirective: https://caddyserver.com/docs/caddyfile/directives/php_fastcgi
But your issue should be fixed by https://github.com/caddyserver/caddy/pull/3570 which is available in v2.2.0-rc.1, please give it a shot.
For next time, please open a new issue with more detail if you think it's a bug (Caddy version, Caddyfile used, logs, etc) or open a thread on the Caddy forums if it's a usage question https://caddy.community and remember to fill out the help thread template.
I'll take a look at the RC to see if that solves the problem first, and then the env subdirective next. I just want to say that I am impressed with the responsiveness on this issue tracker. I realize that I didn't do the proper thing and open up a new bug ticket with detailed info, and just piggy-backed on an issue that resembled the issue I was having. Even still I got some quality responses within 15 minutes of posting.
I'll follow up with the results from those two tests, and if needed, open up a new issue. Thanks!
@francislavoie thanks again for your prompt response. I have been able to resolve my issue using the env subdirective. I believe because the editor is explicitly looking for the value when binding to the debugger, that's why #3570 doesn't resolve it.
So for anyone else with a similar question, trying to debug a PHP application when using Caddy as the web server, here's my php_fastcgi config:
php_fastcgi unix//var/run/php/php7.4-fpm.sock {
env SERVER_PORT 443
}
Just replace the port with whatever you're running your site on (typically 80 for HTTP or 443 for HTTPS) and change the path to fpm if you need to. Thanks again for all of your help.
We _can_ probably find a way to automatically infer this, it might even already have all the pieces there, we'd just need to realize it and set it... I think.
Glad you figured it out! Thanks for posting your solution.
No worries. I understand the reluctance to be opinionated about it. This isn't something I would ever need to add to a production server, as it's use, at least in my case is only during local development.
Most helpful comment
@francislavoie thanks again for your prompt response. I have been able to resolve my issue using the
envsubdirective. I believe because the editor is explicitly looking for the value when binding to the debugger, that's why #3570 doesn't resolve it.So for anyone else with a similar question, trying to debug a PHP application when using Caddy as the web server, here's my
php_fastcgiconfig:Just replace the port with whatever you're running your site on (typically 80 for HTTP or 443 for HTTPS) and change the path to fpm if you need to. Thanks again for all of your help.