Search code examples
phpnginxchrootfpm

nginx passing request to incorrect php-fpm pool


There is a machine with nginx and php-fpm on it. There are 2 servers, 2 php-fpm pools (each one with chroot) and 2 directories that has the same structure and similiar files/php classes.

One pool is listening on 127.0.0.1:22333 while another on 127.0.0.1:22335. The problem is when I make a request to the second server it is somehow executed on the first pool. More strange that sometimes it takes some PHP classes from one directory (of the first pool), sometimes from another. There is not a specific pattern, it seems that it happens randomly.

e.g: Nginx logs show that request comes to the second server and php-fpm logs shows that is was handled in the first pool.

But it never happens other way around (requests to the first server are always executed with first php-fpm pool)

Pools are set up in the same way:

same user
same group
pm = dynamic
pm.start_servers = 20
pm.min_spare_servers = 10
pm.max_spare_servers = 30
pm.max_requests = 300
chroot = ...
chdir = /

php_flag[display_errors] = on
php_admin_value[error_log] = /logs/error.log
php_admin_flag[log_errors] = on
php_admin_value[memory_limit] = 64M
catch_workers_output = yes
php_admin_value[upload_tmp_dir] = ...
php_admin_value[curl.cainfo] = ...

Nginx servers directive for php looks like:

fastcgi_pass 127.0.0.1:2233X;
fastcgi_index  index.php;
include /etc/nginx/fastcgi_params;

fastcgi_param DOCUMENT_ROOT    /;
fastcgi_param SCRIPT_FILENAME  $fastcgi_script_name;
fastcgi_param PATH_INFO        $fastcgi_script_name;
fastcgi_intercept_errors       off;

Solution

  • Had the same problem. Best answer on this so far was on ServerFault which suggested opcache.enable=0, which pointed me to an quite interesting behavior of PHP.

    the APC/OPcache cache is shared between all PHP-FPM pools

    Digging further through opcache documentation I found this php.ini option:

    opcache.validate_root=1
    

    opcache.validate_root boolean

    Prevents name collisions in chroot'ed environments. This should be enabled in all chroot'ed environments to prevent access to files outside the chroot.

    Setting this option to 1 (default is 0) and restarting php-fpm fixed the problem for me.

    EDIT: Searching for the right words (validate_root) I found much more on this bug:

    Following the notes from the bug discussion, you should also consider setting opcache.validate_permission=1