Nginx – How to use different PHP-FPM pools based on directory with different roots in Nginx

nginxPHPphp-fpm

I'm trying to migrate some websites from an older server running Apache and mod_php, to a new server with Nginx and PHP 7 using PHP-FPM. Both sites run a PHP shopping cart in the root of the domain, and a wordpress blog running in the sub folder /news. At the moment on the old servers the word press blog is in a folder called news in the web root (thus mixed in with the shopping carts files) on the new server I'd like to split them out so that each application live in its own separate folder such that:

Files in /home/www/sitename/cart/htdocs are available at https://www.site.tld/

and

Files in /home/www/sitename/wordpress/htdocs are available at https://www.site.tld/news/

I'd also like to be able to use different PHP-FPM pools for security and if needs be to allow me to run either of the apps with a PHP 5 pool until it can be updated to run on PHP 7.

I've got close but it keeps trying to load /news/test.php from /home/www/sitename/wordpress/htdocs//news/test.php
instead of /home/www/manicpanic/wordpress/htdocs/test.php.

Config:

server {
    listen iphere:443 ssl http2;

    #ssl conf

    root /home/www/sitename/cart/htdocs;    
    server_name site.tld www.site.tld;

    rewrite ^(.*)\.v[\d]+\.(css|js|png)$ $1.$2;

    location ~* \.(?:ico|css|js|gif|jpe?g|png)$ {
        expires 30d;
        add_header Pragma public;
        add_header Cache-Control "public";
    }

    location / {
        index index.php index.html index.htm;
        try_files $uri $uri/ /index.html;
    }

    location /news {
        alias /home/www/sitename/wordpress/htdocs;
        location ~ \.php$ {
                fastcgi_pass unix:/run/php/php7.0-fpm-wordpress.sock;
                fastcgi_split_path_info ^(.+\.php)(/.+)$;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                fastcgi_param PATH_INFO $fastcgi_path_info;
                fastcgi_param APPLICATION_ENV production;
                include fastcgi_params;
                fastcgi_index index.php;
                fastcgi_param PHP_VALUE default_charset=ISO-8859-1;
            }

    }

    location ~ [^/]\.php(/|$) {
        fastcgi_pass unix:/run/php/php7.0-fpm-cart.sock;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_param PATH_INFO $fastcgi_path_info;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param APPLICATION_ENV production;
        include fastcgi_params;
        fastcgi_index index.php;
        fastcgi_param PHP_VALUE default_charset=ISO-8859-1;
    }

}

Best Answer

The regular expression location ~ [^/]\.php(/|$) will take precedence over the prefix location /news, unless you use the ^~ modifier. See this document for more.

location ^~ /news {
    alias /home/www/sitename/wordpress/htdocs;
    location ~ \.php$ {
        ...
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $request_filename;
        ...
    }
}

Also, you cannot use $document_root$fastcgi_script_name in conjunction with alias as it creates the wrong pathname. Use $request_filename instead.

Always include fastcgi_params; before using specific fastcgi_param directives, otherwise the specific settings may be silently overwritten.