V2: Caddy php config help

I have a server that has thinkphp as backend, also it has a phpmyadmin interface.

It runs at port 8445 to avoid conflict with the main port.

In caddy v1, the config is sufficient:

https://domain.com:8445/phpmyadmin {
  gzip
  header / Strict-Transport-Security "max-age=31536000;"
  tls /path/crt /path/key
  root /path/phpmyadmin
  fastcgi / /path/php-fpm.sock php
}

https://domain.com:8445 {
  gzip
  header / Strict-Transport-Security "max-age=31536000;"
  tls /path/crt /path/key
  root /path/main_site
  fastcgi / /path/php-fpm.sock php
  rewrite {
    to {path} {path}/ /index.php/{uri}
  }
}

However, in caddy v2, I cannot even get the main site working, main site responded with not controller found, the log shows uri was rewritten correctly, the request method is right.

Hi @WeidiDeng, welcome to the Caddy community!

Thanks for posting your Caddy v1 config for comparison.

Would you mind filling out the Help template (I’ve copied it below) with all the remaining details - including exact error messages and the v2 config you’ve tried.


1. My Caddy version (caddy -version):

2. How I run Caddy:

Please provide all of the relevant information and DO NOT REDACT anything except passwords/keys. Thank you!

a. System environment:

OS, relevant versions, systemd? docker? etc.

b. Command:

paste command here

c. Service/unit/compose file:

paste full file contents here

d. My complete Caddyfile:

paste Caddyfile here
DO NOT REDACT anything except credentials

3. The problem I’m having:

Please describe the issue thoroughly enough so that anyone can reproduce the exact behavior you’re seeing. Be as specific as possible.

4. Error messages and/or full log output:

Please DO NOT REDACT any information except passwords/keys.

5. What I already tried:

6. Links to relevant resources:

1 Like

Thanks for the reply, here is relevant data.

1. My Caddy version ( caddy -version ):

v2.0.0-beta8 h1:eNVaQrLCP9ZpY7zqeq5kI/cYLjJ8XGyzA1MxvpYX1vI=

2. How I run Caddy:

Please provide all of the relevant information and DO NOT REDACT anything except passwords/keys. Thank you!

a. System environment:

OS, relevant versions, systemd? docker? etc.

Plain binary on ubuntu 18.04.

b. Command:

caddy run -config Caddyfile2 -adapter caddyfile 

c. Service/unit/compose file:

Non, I am using commandline to test.

d. My complete Caddyfile:

I’m testing the main site now, tls is off.

domain.com:8445 {
  tls off
  encode gzip
  root * /path/main_site
  php_fastcgi unix//path/php-fpm.sock
  file_server
}

3. The problem I’m having:

Please describe the issue thoroughly enough so that anyone can reproduce the exact behavior you’re seeing. Be as specific as possible.

Only the php index page is available, other url will simply show the index page or error.

4. Error messages and/or full log output:

Please DO NOT REDACT any information except passwords/keys.

No error in the caddy stderr, only those from thinkphp-framework, controller index doesn’t exit.

5. What I already tried:

trying to rewrite what’s ok in v1 to v2.

6. Links to relevant resources:

Caddy v1 php

Thanks for the details @WeidiDeng! And thank you for trying the Caddy 2 beta during its pre-release phase. :slight_smile:

@Whitestrake I wonder if there’s something a little bit wrong about how we’re setting up the php-fpm environment? It sounds like an MVC framework is complaining that a β€œcontroller index” doesn’t exist, maybe a missing file or some wrongly-rewritten URI? (Just throwing out ideas. Too late here for me to be debugging this.)

That’s what it sounds like to me, but I don’t know if it’s a php-fpm setup issue. Both the v1 and v2 PHP setups are pretty spartan on the Caddy side.

@WeidiDeng, I notice that the v2 config has no rewrites in it while the v1 rewrites to try files and then falls back to /index.php{uri}. Is the v2 config you posted the entire config you’re using?

Just a reminder that the v2 php_fastcgi directive does a rewrite under the hood: https://github.com/caddyserver/caddy/wiki/v2:-Documentation#php_fastcgi

(not sure if relevant in this case)

1 Like

Oh, v2 setup isn’t as spartan as I’d thought, then! Might be relevant; the default doesn’t append {uri} to the end of /index.php, maybe the framework expects/requires that?

Could be. @WeidiDeng can test that: simply replace the php_fastcgi directive with the longer form in the docs (don’t do this normally! the single-line directive is usually preferred!) and then tweak the try_files line and see what happens.

1 Like

Using the long form, after some testing, I think I find what’s the problem, here is the long form

domain.com:8445 {
  tls off
  encode gzip
  root * /path/main_site
  
matcher indexFiles {
    not {
        path */
    }
    file {
        try_files {path}/index.php
    }
}
rewrite match:indexFiles {path}/ # No redirect required

# internally rewrite directory URIs to index.php files
try_files {path} {path}/ /index.php/{uri} # Last part is the problem

# proxy any requests for PHP files to backend via FastCGI
matcher phpFiles {
    path *.php
}
reverse_proxy match:phpFiles php-fpm:9000 {
    transport fastcgi {
        split .php
    }
}

  file_server
}

This time caddy emits error 404 when I request a url that should be processed by php, eg. cmd1, instead of passing /index.php/cmd1 to php, caddy tries to find the file or folder by the name. Also when in the short form, caddy invokes php-fpm, but passed an extra /index.php/ (/index.php/index.php/cmd1), causing the controller not found bug.

1 Like

@francislavoie What do you think about this? Should we append /{uri} to the last fallback of /index.php? Or is this a split_path problem?

As far as I can tell, thinkphp is a blatant fork of Laravel: https://github.com/top-think/framework

I don’t think any changes should be required for the fastcgi config to work, as I used the same fastcgi directive in my Caddyfile when I was testing it.

I think it’s most likely an environment issue.

Hmm, so we need to investigate more. There might be two things going on here.

This definitely needs to be fixed. Sounds like a bug on our end?

But I’m having trouble understanding now where we stand. @WeidiDeng this line here:

try_files {path} {path}/ /index.php/{uri} # Last part is the problem

To clarify: Did that make it work for you? I’m wondering because it’s not the same as what the short form does – this is the original:

try_files {path} {path}/index.php index.php

Did you find a variant that does work?

No, because I’m trying to pass the param to the index.php at the root (/index.php), but can’t do that, path resolution stops at trying to find folders.

Can you post the file structure of your app and the unredacted root path you’re using?

For Laravel apps, I typically point root to the public folder of the app. As far as I can tell, think does it the same way: https://github.com/top-think/think/tree/6.0/public

For me, this looks like root * /var/www/myapp/public

The app structure is like the following

tp5 # Thinkphp install root
β”œβ”€β”€ application # Application Logic (Controller, Model, View)
β”‚   β”œβ”€β”€ app1
β”‚   β”œβ”€β”€ app2
β”‚   β”œβ”€β”€ command.php
β”‚   β”œβ”€β”€ common.php
β”‚   β”œβ”€β”€ provider.php
β”‚   └── tags.php
β”œβ”€β”€ build.php
β”œβ”€β”€ CHANGELOG.md
β”œβ”€β”€ composer.json
β”œβ”€β”€ config # Configuration
β”‚   β”œβ”€β”€ app.php
β”‚   β”œβ”€β”€ cache.php
β”‚   β”œβ”€β”€ console.php
β”‚   β”œβ”€β”€ cookie.php
β”‚   β”œβ”€β”€ database.php
β”‚   β”œβ”€β”€ log.php
β”‚   β”œβ”€β”€ middleware.php
β”‚   β”œβ”€β”€ session.php
β”‚   β”œβ”€β”€ template.php
β”‚   └── trace.php
β”œβ”€β”€ extend
β”œβ”€β”€ LICENSE.txt
β”œβ”€β”€ public # **This is the root folder**
β”‚   β”œβ”€β”€ favicon.ico
β”‚   β”œβ”€β”€ index.php
β”‚   β”œβ”€β”€ robots.txt
β”‚   β”œβ”€β”€ router.php
β”‚   └── static
β”œβ”€β”€ README.md
β”œβ”€β”€ route
β”‚   └── route.php
β”œβ”€β”€ runtime
β”‚   β”œβ”€β”€ cache
β”‚   β”œβ”€β”€ log
β”‚   └── temp
β”œβ”€β”€ think
β”œβ”€β”€ thinkphp
β”‚   β”œβ”€β”€ base.php
β”‚   β”œβ”€β”€ composer.json
β”‚   β”œβ”€β”€ CONTRIBUTING.md
β”‚   β”œβ”€β”€ convention.php
β”‚   β”œβ”€β”€ helper.php
β”‚   β”œβ”€β”€ lang
β”‚   β”œβ”€β”€ library
β”‚   β”œβ”€β”€ LICENSE.txt
β”‚   β”œβ”€β”€ logo.png
β”‚   β”œβ”€β”€ phpunit.xml.dist
β”‚   β”œβ”€β”€ README.md
β”‚   └── tpl
β”œβ”€β”€ thinkphp.md
└── vendor

Tp5 path is /path/to/tp5, the public path (i.e, the path that is served from the root) is /path/to/tp5/public, but the application is /path/to/tp5/application, which is different from laravel.

Yeah, that all looks fine. If the root in your Caddyfile is set correctly to your public dir, then it should work just fine.

My config looks like this, with a Laravel app:

:80

root * /var/www/public

encode gzip

php_fastcgi php-fpm:9000

file_server
1 Like

After reading the thinkphp document and error page, I found out that I have used thinkphp’s routing module which depends on path_info variable, however, caddy failed to pass that value, causing url resolution failed. That results in thinkphp using fallback index controller which doesn’t exist.

1 Like

Aha, now we’re getting somewhere. Sounds like the v2 implementation isn’t passing down some server params that v1 did.

@matt I’ll do some testing and I’ll let you know what I think is missing, but I think it’s a safe bet to provide the PATH_INFO var to fastcgi.

1 Like

I compared the fastcgi environment variables that Caddy v1 and v2 send over fastcgi, I see no relevant differences.

I went through the thinkphp v5 and v6 framework source code (specifically Request.php, which is where the request is bootstrapped from $_SERVER env vars).

The PATH_INFO var is not needed because there are fallbacks to use REQUEST_URI instead, which should be correctly set. You can probably test this yourself, try dumping $_SERVER in your index.php before the app is booted.

At this point I’m back to my previous answer of β€œit’s not Caddy, it’s your environment”. There must be something that you didn’t share with us that’s causing your issue.

Currently I’m using thinkphp 5.1, Request.php only treats REQUEST_URI as PATH_INFO when run as cli-server

The interface according to the log is CGI/1.1