2

Having a very hard to trying to figure this out. I have changed my website from another platform to Joomla and now Nginx is unable to handle old urls.

My Old Urls were like this:

example.com/home.php
example.com/contact-us.php

My New Joomla SEF Urls are like this:

example.com/home
example.com/contact-us

I have the following Nginx config as per Joomla guide:

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

 # Process PHP
 location ~ \.php$ {
            try_files $uri =404;
            fastcgi_split_path_info ^(.+\.php)(/.+)$;

            fastcgi_pass   unix:/var/run/php5-fpm.sock;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
            include        fastcgi_params;
 }

I want Nginx to pass these old urls to Joomla to handle it. Now, what is happening is, Nginx is treating these old urls as php files and then showing me this No input file specified. error. I then changed the try_files inside the php block to try_files $uri /index.php?$args; so my Nginx config looks like this:

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

 # Process PHP
 location ~ \.php$ {
            try_files       $uri /index.php?$args;
            fastcgi_split_path_info ^(.+\.php)(/.+)$;

            fastcgi_pass   unix:/var/run/php5-fpm.sock;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
            include        fastcgi_params;
 }

Is this valid? Would this cause an infinite loop issues in some cases? Is this is right way to do this? I didint find any solution similar to this. Can someone guide me please?

Neel
  • 1,421
  • 7
  • 21
  • 35

1 Answers1

3

location / is never used

The problem you have is related to location precedence (emphasis added).

nginx first searches for the most specific prefix location given by literal strings regardless of the listed order. [...] Then nginx checks locations given by regular expression in the order listed in the configuration file. The first matching expression stops the search and nginx will use this location. If no regular expression matches a request, then nginx uses the most specific prefix location found earlier.

As such, this location block:

location ~ \.php$ {
    try_files $uri =404; # <-

Matches this request:

example.com/home.php

and no other location block is relevant.

As you already realize, this means that nginx will attempt to find and serve home.php resulting in a 404.

Use a @location for the main index.php file

Normally the only php file of relevance is index.php, you can make use of it like so:

try_files $uri $uri/ @joomla;

location @joomla {
    include fastcgi_params;
    fastcgi_pass    unix:/var/run/php5-fpm.sock;
    fastcgi_param   SCRIPT_FILENAME     $document_root/index.php;
    fastcgi_param   SCRIPT_NAME         $document_root/index.php;
    fastcgi_param   DOCUMENT_URI        /index.php;
    fastcgi_index   index.php;
}

Use another location block for *.php requests

In addition to a front controller, joomla allows/expects other php files to be directly accessed such as /administrator/index.php. To allow access to them without trying to process missing php files:

location ~ \.php$ {
    try_files $uri @joomla;

    include fastcgi_params;
    fastcgi_pass    unix:/var/run/php5-fpm.sock;
    fastcgi_index   index.php;
    fastcgi_param   SCRIPT_FILENAME  $document_root$fastcgi_script_name;
}

This will allow direct access to other php files (which ordinarily, isn't a good thing...) falling back to use /index.php, via the @joomla location, for any php file requests that don't exist.

Note that the above setup is also in the documentation.

AD7six
  • 2,810
  • 2
  • 20
  • 23
  • Thank you AD7six. But since Joomla would also need other php files for it to work internally (although not accessed directly through browser), would the above condition prevent other php files from being accessed by Joomla itself? – Neel Jan 09 '15 at 14:49
  • it seems, the index.php is also being rewritten to `index`. – Neel Jan 09 '15 at 14:54
  • Now amended following the cursory glance I gave joomla's demo app =). – AD7six Jan 09 '15 at 15:10
  • I am getting a lot of 404 errors and in console I can see that its looking for files with absolute path after domain name like this `example.com/var/www/site/template/protostar/css/template.css`, etc.. Its not respecting the document root added in server block it seems – Neel Jan 09 '15 at 15:32
  • Sorry AD7six, when I look at the edited code, isint it doing the same as what I initially had except its has the extra @joomla block? I mean when we have the `location ~ \.php` block now, is there a need for `location @joomla` since the second php block can override it and beats the purpose? – Neel Jan 09 '15 at 15:44
  • If I can use try_files for php block, then can point me out on why this method is wrong: `try_files $uri /index.php?$args;` (last code block in my question) plz? Arent I telling Joomla to first look for the php file, if it doesnt exist, pass the php file as an argument to Joomla's index.php and therefore leaving it to Joomla to handle 404 or redirection based on the Joomla setting? Is it not right? I am confused since my initial method seems to work but concerned since you had mentioned try_files are never used there. Sorry for my questions :) – Neel Jan 09 '15 at 16:02
  • bad paths are likely bad fastcgi config [I get no such errors](http://dump.ad7six.com/joomla-dev.png) - check how the paths are derived and you'll probably find the problem. Yes you could if you want drop the `@joomla` location but it's more intersting imo to be abl to do say: `error_page 404 = @joomla;` rather than `error_page 404 = /index.php;`. – AD7six Jan 09 '15 at 17:50