Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

I have a server context which is rooted in a login application. The login application handles, well, logins, and then returns a redirect to "/app" on the same server if a login is successful. The application is rooted elsewhere, which is handled by the location block shown here:

location ^~ /app {
        alias /usr/share/nginx/www/website.com/content/public;
        location ~ \.php$ {
                try_files $uri =404;
                fastcgi_pass unix:/tmp/php5-fpm.sock;
                include fastcgi_params;
        }
}

This works just fine, however the $uri getting passed to PHP still contains /app, even though I am using alias rather than root. Because of this, the try_files directive fails to a 404 unless I link app -> ./ in /usr/share/nginx/www/website.com/content/public.

It's obviously silly to have that link in there, and if that link ever gets lost, bam dead website without an obvious cause.

The next thing I tried...

Was to remove the try_files directive entirely. This allowed me to rm the app link in my /public folder, and PHP had no problem locating the file and executing it. I used that to dump my $_SERVER global from PHP, and found that "SCRIPT_FILENAME" => "/usr/share/nginx/www/website.com/content/public/index.php" when the browser URI is /app.

This is exactly right. Based on my fastcgi_params below, this led me to beleive that try_files $request_filename =404; should work, but no dice. nginx still doesn't find the file, and returns 404.

So for right now, it will only work without any try_files directive. PHP finds the file, whereas try_files could not. I understand this may be a PHP security risk. Can anyone indicate how to move forward? The nginx logs don't contain anything relating to the failed try_files attempt, as far as I can see.

fastcgi_aparams

fastcgi_param   QUERY_STRING        $query_string;
fastcgi_param   REQUEST_METHOD      $request_method;
fastcgi_param   CONTENT_TYPE        $content_type;
fastcgi_param   CONTENT_LENGTH      $content_length;

fastcgi_param   SCRIPT_FILENAME     $request_filename;
fastcgi_param   SCRIPT_NAME     $fastcgi_script_name;
fastcgi_param   REQUEST_URI     $request_uri;
fastcgi_param   DOCUMENT_URI        $document_uri;
fastcgi_param   DOCUMENT_ROOT       $document_root;
fastcgi_param   SERVER_PROTOCOL     $server_protocol;

fastcgi_param   GATEWAY_INTERFACE   CGI/1.1;
fastcgi_param   SERVER_SOFTWARE     nginx/$nginx_version;

fastcgi_param   REMOTE_ADDR     $remote_addr;
fastcgi_param   REMOTE_PORT     $remote_port;
fastcgi_param   SERVER_ADDR     $server_addr;
fastcgi_param   SERVER_PORT     $server_port;
fastcgi_param   SERVER_NAME     $server_name;

fastcgi_param   HTTPS           $server_https;
share|improve this question
    
According to this forum post this should work, but I couldn't get it to either. I suspect that the nested location block is interfering somehow. –  mgorven Mar 28 '12 at 5:05
    
Don't have your app in /app at all. It's pointless, loses you SEO points, and terribly confuses anybody who has to look at this. If you really want to go through this pain, you need to use fastcgi_split_path_info. –  Michael Hampton Oct 10 '12 at 0:18

2 Answers 2

In order to make it work, fastcgi_param SCRIPT_FILENAME $request_filename needs to be copied in the location block, like this:

location ^~ /app {
        alias /usr/share/nginx/www/website.com/content/public;
        location ~ \.php$ {
                include fastcgi_params;
                fastcgi_param SCRIPT_FILENAME $request_filename;

                fastcgi_pass unix:/tmp/php5-fpm.sock;
                try_files $uri =404; 
                # NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
                fastcgi_split_path_info         ^(.+\.php)(/.+)$;
                fastcgi_index               index.php;
        }
}

This is because in included configuration files, $request_filename dose not reflect the new alias, due to how nginx inherits configuration values between levels.

share|improve this answer

Check your fastcgi_params. Most likely your SCRIPT_FILENAME is defined as $document_root$fastcgi_script_name which explicitly tells it not to consider alias (the $document_root part is the explicit part)

If you want to use alias with PHP you should probably define SCRIPT_FILENAME as $request_filename which takes alias into consideration.

share|improve this answer
    
Thanks for the reply. I have edited the OP to contain my fastcgi_params. Looks like they are already configured as you suggest? –  Carson C. Jan 10 '12 at 12:33
    
I think I misunderstood you then, is your $_SERVER['REQUEST_URI'] variable the one showing up as /app still? Then that's expected behaviour as you have it defined it as REQUEST_URI $request_uri; –  Martin Fjordvald Jan 10 '12 at 14:46
    
I realized this morning that my question was horribly confusing, because "app" occurred in the path twice. I have edited the post so that it's now clear where "app" is the offending bit. I also added a section on what I have tried so far. Sorry for the initial confusion, and thank you for your assistance. –  Carson C. Jan 11 '12 at 14:11

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.