• If you are still using CentOS 7.9, it's time to convert to Alma 8 with the free centos2alma tool by Plesk or Plesk Migrator. Please let us know your experiences or concerns in this thread:
    CentOS2Alma discussion

Enabling php-fpm + nginx and link rewrite

gennolo

Basic Pleskian
I recently switched some customer domains from php-cgi (apache served) to php-fpm (nginx served with apache as reverse proxy using the plesk-php56 package).

Everything went flawlessly and I had a great boost of performance - but I have an issue with url rewriting that is driving me crazy.

I have some websites running the prestashop cms.

If the cms is configured to have multiple languages the starting URL would be something like :

http://www.website.com/en/
http://www.website.com/fr/
http://www.website.com/it/

In this condition Nginx returns a 404 not found error when opening the page.

Of course with an apache-only configuration the url opens correctly and returns the homepage.

I can confirm that even with php-fpm, the native apache prestashop rewrite rules in ".htaccess" are working properly once the web request arrive to apache (because of the reverse proxy configuration)... but this particular request seems to be processed by nginx directly ...

The problems seems to be the trailing slash, in fact if I type the URL with "/en" - the site opens correctly.

It looks like nginx search for index file, not being able to find it.

Those are the solution I tried without success :

1 - Using the .htaccess to nginx converter (same problem)
2 - Using a nginx rewrite rule ( rewrite ^/(.*)/$ /$1 permanent; ) in nginx.conf file to force redirecting slash requests to non-slash requests but this lead me to other redirection-loop url troubles.

any idea for a proper configuration ?
 
Hi gennolo,

this issue is not at all a "Plesk related" issue. Please consider to use a Google search ( http://lmgtfy.com/?q="nginx"+"prestashop"+"rewrite"+site:www.prestashop.com ), if you would like to get recommendation for a third party component.

Please keep in mind, that suggestions from the www for nginx rewrite rules often include parts like
Code:
...
       location ~ \.php$ {
                try_files $uri =404;
                include /etc/nginx/fastcgi_params;
                fastcgi_pass unix:/var/run/php5-fpm.sock;
                fastcgi_index index.php;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                fastcgi_intercept_errors on;
       }
...
Before you try to add such a rewrite rule, please have a closer look on your own, domain specific nginx configuration at "/var/www/vhosts/system/website.com/conf/" ( "last_nginx.conf" or "last_ip_default.conf" ). You will notice, that if you already choosed PHP5-FPM as your PHP-handler for your (sub)domain, then Plesk already added a location definition for "... location ~ \.php(/.*)?$ ...". You don't need that and it will not meet your PHP-handler configuration, as you will as well notice, when having a look at your current config - files ( it is as well not possible to add double location definitions! ).


In addition, please consider to add errors from log - files ( /var/www/vhosts/system/website.com/logs/ ) , because we can help you far better, when you provide errors from log - files, instead of trying to describe an issue/problem and try to include as well existent configuration files for investigations.
 
I honestly thought that using nginx as a reverse proxy would allow me to use the apache .htaccess settings without conversion problems and having to edit the configuration files of nginx.

In fact, everything worked fine except the reported problem of 404 nginx error in subfolders.

However adding this line :
Code:
try_files $uri $uri/ /index.php?$args;
to
Code:
location ~ /$ {
of my vhost configuration did the trick.

This post :


led me to the solution.
 
For anybody else occurring in this problem (Prestashop , Wordpress and other CMS widely use this type of redirections ) when switching in PHP-FPM
I was able to fix it in batch on all domains by editing the general Nginx Plesk template configuration :

Code:
/usr/local/psa/admin/conf/templates/default/domain/nginxDomainVirtualHost.php


and adding the try_files directive in the proper section , and then :

Code:
/usr/local/psa/admin/sbin/httpdmng --reconfigure-all
 
Hi gennolo,

please don't encourage Plesk users to edit default templates. It is just false and will lead to issues/problems/failures and in addition, your changes will be lost in case of updates/upgrades/patches from Plesk.


If you really think, that adding additional directives for apache and/or nginx is not sufficient ( Home > Subscriptions > YOUR_DOMAIN.COM > Websites & Domains > Apache & nginx Settings ) for what ever reason, then the documentation will guide you, how to setup CUSTOM webserver configuration files:

 
@gennolo,

In response to

I honestly thought that using nginx as a reverse proxy would allow me to use the apache .htaccess settings without conversion problems and having to edit the configuration files of nginx.

it has to be stated that .htaccess files have no or little added value: after all, nginx as proxy is doing most of the work, before anything touches Apache and it´s .htaccess files.

In most cases, the .htaccess file can be deemed to be "irrelevant" and can be safely discarded.

It is important to note that having Nginx as a proxy also implies that you have to translate the .htaccess rules to Nginx configuration directives, to be placed in Nginx conf files.

Finally, you stated

However adding this line :
Code:
try_files $uri $uri/ /index.php?$args;
to
Code:
location ~ /$ {
of my vhost configuration did the trick.

and the try_files directive (indeed) allows for pretty permalinks in WordPress, but this directive should not be necessary (in standard configurations).

However, the "location ~/$" part of your solution is completely wrong: it should simply be "location /" as in

location / {
try_files $uri $uri/ /index.php?$args;
}


Hope the above helps.

Regards....
 
@bulent,

Do not change the nginxDomainVirtualHost.php file.

In most cases, there is no necessity to alter the default template for Nginx, everything can be done with customizations of config files.

And even if you want to automate customization of config files by using custom templates, read up on creating custom templates in the Plesk manuals.

The above is just to prevent that you are doing something that can (and often will) result in failures on all domains.

Regards...
 
@bulent,
In most cases, there is no necessity to alter the default template for Nginx, everything can be done with customizations of config files.

I already tried to use the "Additional Nginx directives" .
I was aware of the function and it was my first idea to avoid customizing main templates and keep everything original.

However If I add this code:

Code:
location /{
try_files $uri $uri/ /index.php?$args;
}

I got the error:
Invalid nginx configuration: nginx: [emerg] duplicate location "/" in /var/www/vhosts/system/xxxxxxx.com/conf/vhost_nginx.conf:1 nginx: configuration file /etc/nginx/nginx.conf test failed

Because of the location being already defined in the Plesk main template, I guess.

Inserting :

Code:
location ~/${
try_files $uri $uri/ /index.php?$args;
}

Returned no error - But I still had the original issue (404 redirect error when pointing to mysite.com/en/ )

I also tried to add "try_files $uri $uri/ /index.php?$args;" without "location" but it didn't work because the rule was put out of scope, I guess.

So the only solution (for me) was to editing the main Plesk PHP template.
If you know the way to handle it with a custom directive inside the *vhost* configuration, it would really appreciated.

@trialotto: Thank you for pointing me out the way to create custom templates. I wasn't aware of this possibility.
 
@trialotto
Yepp,
I will not modify anything, you are totaly right. I'm experimenting with one VPS, thats all.
@gennolo
Try rewrite code below in additional nginx directives.
Code:
rewrite !\.(js|ico|gif|jpg|png|css|pdf|mov|mp3|eot|svg|ttf|woff|otf|txt)$ /index.php break;
rewrite /wp-admin/$ /wp-admin/index.php break;
rewrite /$ /index.php break;

This code works in most cases. I had only problems with Woocommerce install, and the problem was only when you complete order. In that case try that one below:
Code:
if (!-e $request_filename){
  rewrite ^(.*)$ /index.php break;
}
 
@bulent,

Even though I must admit that I admire the idea that you would like to help out, be aware of the following:

a) "if is evil" in Nginx: in nginx conf files, the "if statement" should be prevented, if possible (and that is always possible, with proper usage of directives)

b) whenever possible, return directives should be used instead of rewrite directives

c) in the case of any rewrite directive, choose carefully beteen "break" and "last": in most cases, last is more efficient and should be preferred

d) all the above mentioned should be viewed in the light of proper configuration of server and location blocks: one can not "just add" some directive, one always has to consider the whole matching logic of Nginx and adjust config files to make Nginx as efficient (and compact) as possible.

Note that I will respond to @gennolo, in order to illustrate the above, point d in particular.

Regards....
 
@gennolo,

I was busy writing a long response, but I something remarkable:
mysite.com/en/

Are you having the domain mysite.com in Plesk? And is /en/ a normal subdirectory?

If the root is "mysite.com" and the normal site files are in /var/www/vhosts/mysite.com/httpdocs/en/, then use:

location /en/ {
try_files $uri $uri/ /en/index.php?$args;
}

and if, by coincidence, index.php is in /var/www/vhosts/mysite.com/httpdocs/, just use:

location /en/ {
try_files $uri $uri/ /index.php?$args;
}

Anyway, check the value for the root directive in the file /var/www/vhosts/system/mysite.com/conf/nginx.conf, that would be really helpful.

Regards....
 
@trialotto

First of all - Thank you in advance for your efforts.

I take as example one of the Prestashop website where I'm having problems.

The domain is configured as you say.
The CMS files are stored in /var/www/vhosts/website.com/httpdocs
but there is no /en/ physical directory on the server at all.

The /en/ redirect is made by Prestashop itself when multilanguage feature is enabled (and rewrite feature is enabled aswell).

This is the same concept of the Wordpress permalinks that creates links like website.com/name-of-the-article/

In fact, when setting the site in apache/php-cgi everything works properly.
.htaccess file generated by Prestashop / Wordpress do the work of redirecting to the website in the correct language or to the right article.

By setting the site in php-fpm/nginx (great overall performance boost!) - although the .htaccess is still process properly (all the rewrite rules of the site works ... for example in prestashop all image links are written with the product name - they work exactly as before without any changes ..)
the /en/ urls stopped working returning to 404 Not Found *nginx* page.

From what I understand this kind of requests do not come to Apache, but are processed directly by nginx that not finding an "index" file (as specified in location section of default nginx Plesk template) , it returns 404.

And here started the confusion...

Why Apache .htaccess still works in php-fpm/nginx ? It is because of Nginx being a reverse proxy , right ?
If so, why the /en/ request is directly served by nginx returning a 404 ?

Hence the search for a non-invasive solution in order to have a good configuration templates with php-fpm and Prestashop / Wordpress ... But so far the only one I found was expected overwriting /usr/local/psa/admin/conf/templates/default/domain/nginxDomainVirtualHost.php
as explained here -> http://www.curvve.com/blog/servers/...nginx-and-php-fpm-not-rewrite-wordpress-urls/
 
@gennolo

Note that

The /en/ redirect is made by Prestashop itself when multilanguage feature is enabled (and rewrite feature is enabled aswell).

This is the same concept of the Wordpress permalinks that creates links like website.com/name-of-the-article/

is not entirely correct: the concept is the same, the coding and therefore the process is entirely different.

This also implies that you cannot use WordPress related Nginx configuration for Prestashop: it will simply not work, at least in most cases.

From what I understand this kind of requests do not come to Apache, but are processed directly by nginx that not finding an "index" file (as specified in location section of default nginx Plesk template) , it returns 404.

This is true, fpm is processing the requests and, somehow, the prettified urls are causing a 404 error.

But keep in mind that it is "strange" to have Nginx process php, Nginx is intended as and functions best as either a pure proxy or a pure (lightweight) webserver.

Combining the functions of a webserver and a proxy in one Nginx instance is not natural, but that is what (in essence) happens when having Nginx serving php with fpm.

Let´s return to the above later.

By setting the site in php-fpm/nginx (great overall performance boost!) - although the .htaccess is still process properly (all the rewrite rules of the site works ... for example in prestashop all image links are written with the product name - they work exactly as before without any changes ..)
the /en/ urls stopped working returning to 404 Not Found *nginx* page.

Ehm, to be honest, Nginx + fpm is not that good at all: if you were running some "heavy load" stress tests, you would discover that Nginx processing php is performing poorly.

Again, it has to be noted that it is not natural to effectively make your Nginx proxy to be or to mimick a web server.

From what I understand this kind of requests do not come to Apache, but are processed directly by nginx that not finding an "index" file (as specified in location section of default nginx Plesk template) , it returns 404.

Actually, Nginx is processing the php requests..... Apache is hardly a part of the equation.

Why Apache .htaccess still works in php-fpm/nginx ? It is because of Nginx being a reverse proxy , right ?
If so, why the /en/ request is directly served by nginx returning a 404 ?

The .htaccess file should not "work", except in the case of misconfiguration or (exceptional) requests that still reach Apache.

In essence, with Nginx processing php, most or all (depending on proper configuration) php requests are handled by fpm and as such Nginx is not really a pure (!) proxy.

The issue with "/en/ requests" is simply the fact that the directory does not exist: it is only the result of prettifying URLs.


In general, I would give you the advice to run fpm on Apache and use Nginx as a pure proxy: just select Apache + php-fpm under "PHP Settings".

With this setup, many issues caused by the Nginx php processing will not occur anymore AND the Nginx configuration can be relatively simple.

The penalty on performance is small in the case of small page loads and, moreover, performance can increase in the case of heavy page loads.


Finally, note that Prestashop normally requires a lot of rewrite rules, but running fpm on Apache would simplify the whole issue to running "standard settings".

Naturally, if you want me to have a look at the Prestashop setup (for Nginx with fpm), just start a personal conversation.

Regards.....
 
The .htaccess file should not "work", except in the case of misconfiguration or (exceptional) requests that still reach Apache.
It should be so, but it is not, and I it looks strange to me too.
I did not make any strange configuration.
I installed Plesk 12.5 on Centos 6 x64, configured some Prestashop domains in php-cgi , then switched them to PHP-FPM (served by nginx) using the Plesk PHP 5.6 package (not the vendor one).
The extension ".htaccess to nginx converter" , by the way, is uninstalled.
In this setup, all Prestashop rewriting are work properly.
As previously stated, there are some custom rewriting like "www.domain.tld/34-name-of-the-product-image.jpg" that are definitely in the htaccess.
So, htaccess is not totally ignored in my case.

In general, I would give you the advice to run fpm on Apache and use Nginx as a pure proxy: just select Apache + php-fpm under "PHP Settings".
Actually I don't have this option , at least with Plesk provided PHP 5.6 Package. I only have PHP-CGI/Apache and PHP-FPM/Nginx choice in the domain configuration dropdown. Am I missing something ?
I see there is the way to install generic FPM support from OS Vendor through Plesk autoinstaller - but being in a Centos 6 OS this would lead me to install a custom OS-PHP package (OS-stock-PHP is quite outdated... 5.3 version) and I will lose the benefits of Plesk-Maintained PHP packages.

EDIT: I tried to install "FPM support from OS Vendor" from Plesk Installer in a local environment , but it appears to add php-fpm / nginx support for the OS Vendor PHP - So no straightforward way to enable PHP-FPM served by Apache.
 
Last edited:
Actually I don't have this option , at least with Plesk provided PHP 5.6 Package. I only have PHP-CGI/Apache and PHP-FPM/Nginx choice in the domain configuration dropdown. Am I missing something ?
Yepp,
there is option for "php-fpm served by apache" and packages are mainteined by odin
 

Attachments

  • screenshot.jpg
    screenshot.jpg
    241.9 KB · Views: 31
@gennolo,

You stated:
As previously stated, there are some custom rewriting like "www.domain.tld/34-name-of-the-product-image.jpg" that are definitely in the htaccess.

The "rewriting" is done by Prestashop (i.e. the php scripts), it has nothing to do with .htaccess.

The main reason for me suggesting that you should revert to Apache + fpm is that Nginx config files become rather complex/elaborate, when using Nginx + fpm.

One can find examples online everywhere, but nobody seems to bother to mention the performance penalty of those elaborate Nginx config files.

To illustrate, more than 10 "rewrite" lines are often advised (note: I find that peculiar, since a more compact set of rewrite rules can be made) and it must be clear that a well-configured, performant Apache ( + fpm) server is fast enough OR even faster, if a lot of requests per second are made (and each of those requests must go through a number of complex regexp matchting patterns, necessary in the Nginx config files).

In short, be aware of the "challenges" in using Nginx for some applications and also be aware of the fact "back to basics" is key: the most complex setup is often not the best one.

To illustrate the relevance of "back to basics": you have been focusing on fastcgi (i.e. php-fpm), but you have been forgetting Redis Cache in the process.

Even though fastcgi and Redis Cache are totally different things, using Redis Cache on Prestashop will outperform any other alternative stack.

And there you have the general "rule of thumb": investigate (all) alternatives, choose a couple of them, test them and discard any alternative that results in issues/problems.

Hope the above helps.....

Regards...
 
@bulent
@trialotto


So here's where the problem lies.
I have no PHP-FPM / Apache support option to choose, neither in Plesk PHP , nor in vendor PHP.
Otherwise I would have chosen from the beginning and that this topic would never have existed :)

httpd -v says:
Server version: Apache / 2.2.15 (Unix)
Server built: 24 Aug 2015 17:52:49

Plesk box is a standard Centos 6.7 x64 setup with standard + atomic repo.
I also installed the PHP-FPM support from the autoinstaller , but it appears to only add the FPM support (served by *NGINX*) for the vendor PHP version.

Here is what i see in the dropdown :

2yvtlip.jpg



@trialotto
Thanks again for your clear explanation. At this point I rather prefer to switch to the Apache / FPM way... If I find the way to enable it
 
@gennolo

Well, with this statement

httpd -v says:
Server version: Apache / 2.2.15 (Unix)
Server built: 24 Aug 2015 17:52:49

your issue becomes clear: you should have an Apache 2.4.x (also 2.4.7 on CentOS, if I am not mistaken).

Just install or reinstall the Apache packages with the (command line) autoinstaller, that would be probably enough to update most of the Plesk related Apache packages.

Check the results afterwards, by getting the installed packages: yum list installed | grep apache (and yum list installed | grep fpm).

By the way, it is kind of strange that you have the current (and limited) set of Apache/Nginx options, did you do anything specific when installing Plesk and/or CentOS?

Regards....
 
@trialotto
I did nothing more than installing OS and Plesk, the OS (CentOS 6) is shipped with Apache 2.2 , as far as I know Apache package is not Plesk served, but it is the one provided with the OS.
Are you sure that autoinstaller is able to upgrade automatically to Apache 2.4 ? If so, I will backup the VM and give a try.
 
Back
Top