I've looks up and down and, while this has been answered dozens of times, I can't get it to work. I'm trying to get apache style multiviews on my PHP site running under nginx. In this case I don't care about all file extensions, just php. So i have my try_files directive:
try_files $uri $uri.php $uri/ $1?$args $1.php?$args
which is all good and dandy, except that when I visit a PHP page without the PHP file extension, the PHP doesn't get rendered and just gets dumped straight to the browser. I see why (PHP is only being used when the location ends in .php, but I've got no idea how to fix it. Here's my config:
server {
listen 80; ## listen for ipv4; this line is default and implied
#listen [::]:80 default ipv6only=on; ## listen for ipv6
root /usr/share/nginx/www;
index index.php index.html index.htm;
server_name inara.thefinn93.com;
location / {
root /usr/share/nginx/www;
try_files $uri $uri.php $uri/ $1?$args $1.php?$args;
}
location ~ ^(.+\.php)$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_index index.php;
include fastcgi_params;
}
location ~ /\.ht {
deny all;
}
}
In your scenario, the location / is the last processed location setting. Having a try_files on it won't make it past the location ~ ^(.+\.php)$ setting (unless it ends with ".php"), therefore not being forwarded to the fastcgi upstream. You might use a named location for that purpose (locations starting with "#").
Here's an example based on your configuration:
# real .php files only
location ~ ^(.+\.php)$ {
# try_files is not needed here. The files will be checked at "location /"
# try_files $uri =404;
# do not split here -- multiviews will be handled by "location #php"
# fastcgi_split_path_info ^(.+\.php)(/.+)$;
# fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass unix:/var/run/php5-fpm.sock;
# also not needed here/with try_files
# fastcgi_index index.php;
include fastcgi_params;
}
# pseudo-multiviews
location #php {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
fastcgi_index index.php;
fastcgi_pass unix:/var/run/php5-fpm.sock;
# search for the split path first
# "$uri/" is not needed since you used the index
try_files $fastcgi_script_name $uri.php =404;
}
# this should also be before "location /"
location ~ /\.ht {
deny all;
}
location / {
root /usr/share/nginx/www;
# if file does not exist, see if the pseudo-multiviews work
try_files $uri #php;
}
Related
lets say I've a path like:
/var/www/myside/
that path contains two folders... let's say
/static and /manage
I'd like to configure nginx to have an access to:
/static folder on / (eg. http://example.org/)
this folder has some .html files.
/manage folder on /manage (eg. http://example.org/manage) in this case this folder contains Slim's PHP framework code - that means the index.php file is in public subfolder (eg. /var/www/mysite/manage/public/index.php)
I've tried a lot of combinations such as
server {
listen 80;
server_name example.org;
error_log /usr/local/etc/nginx/logs/mysite/error.log;
access_log /usr/local/etc/nginx/logs/mysite/access.log;
root /var/www/mysite;
location /manage {
root $uri/manage/public;
try_files $uri /index.php$is_args$args;
}
location / {
root $uri/static/;
index index.html;
}
location ~ \.php {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_index index.php;
fastcgi_pass 127.0.0.1:9000;
}
}
The / works correctly anyway manage doesn't. Am I doing something wrong? Does anybody know what should I change?
Matthew.
To access a path like /var/www/mysite/manage/public with a URI like /manage, you will need to use alias rather than root. See this document for details.
I am assuming that you need to run PHP from both roots, in which case you will need two location ~ \.php blocks, see example below. If you have no PHP within /var/www/mysite/static, you can delete the unused location block.
For example:
server {
listen 80;
server_name example.org;
error_log /usr/local/etc/nginx/logs/mysite/error.log;
access_log /usr/local/etc/nginx/logs/mysite/access.log;
root /var/www/mysite/static;
index index.html;
location / {
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_pass 127.0.0.1:9000;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $request_filename;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
}
location ^~ /manage {
alias /var/www/mysite/manage/public;
index index.php;
if (!-e $request_filename) { rewrite ^ /manage/index.php last; }
location ~ \.php$ {
if (!-f $request_filename) { return 404; }
fastcgi_pass 127.0.0.1:9000;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $request_filename;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
}
}
}
The ^~ modifier causes the prefix location to take precedence over regular expression locations at the same level. See this document for details.
The alias and try_files directives are not together due to this long standing bug.
Be aware of this caution in the use of the if directive.
I want to be able to convert the following link:
http://domain.com/foo/bar
into http://domain.com/index.php?controller=foo&action=bar
using php5-fpm. I also want to be able to access static files inside www/ folder. How do I do that? This is what I have so far:
server {
charset utf-8;
client_max_body_size 8M;
listen 80; ## listen for ipv4
server_name domain.com;
root /var/www/domain.com/www;
index index.php;
access_log /var/log/nginx/domain.com.access.log;
error_log /var/log/nginx/domain.com.error.log;
location / {
rewrite ^([a-zA-Z0-9]+)/([a-zA-Z0-9]+)/?$ /index.php?controller=$1&action=$2;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
}
location ~ /\.(ht|svn|git) {
deny all;
}
}
But it gives me blank page and no get parameters. How should I do this?
The try_files directive is useful when serving static files, if they exist, and rewriting the URI if they do not. See this document for details.
There are a number of ways to achieve this, for example:
location / {
try_files $uri $uri/ #rewrite;
}
location #rewrite {
rewrite ^([a-zA-Z0-9]+)/([a-zA-Z0-9]+)/?$ /index.php?controller=$1&action=$2 last;
return 404;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_pass unix:/var/run/php5-fpm.sock;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $request_filename;
}
I have a development box that each user has a www folder in the home dir. NGINX is hosting those dirs from http://IP ADDRESS/USERNAME. And this works great. I want to get PHP working in the same fashion.
/etc/nginx/sites-available-default:
server {
listen 80 default_server;
listen [::]:80 default_server ipv6only=on;
#root /usr/share/nginx/html;
#index index.html index.htm;
# Make site accessible from http://IP ADDRESS/
server_name IP ADDRESS;
#location ~ ^/(.+?)(/.*)?$ {
location ~ ^/(.+?)(/.*)?$ {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
#try_files $uri $uri/ =404;
# Uncomment to enable naxsi on this location
# include /etc/nginx/naxsi.rules
alias /home/$1/www$2;
index index.html index.htm index.php;
include /etc/nginx/php.fast.conf;
autoindex on;
}
php.fast.conf file:
location ~ \.php$ {
fastcgi_split_path_info ^(.+?\.php)(/.*)?$;
fastcgi_pass unix:/var/run/php5-fpm.sock;
# fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_FILENAME /home/$1/www$2$fastcgi_script_name;
include /etc/nginx/fastcgi_params;
}
As you can see I have tried a few variations but seem to continue to receive the following error in the log: *1 FastCGI sent in stderr: "Primary script unknown" while reading response header from upstream, client.
When attempting to render a simple PHP info page The page displays "file not found"
Other info:
Server = ubuntu 14.x
Latest Nginx
Digital Ocean Droplet
Thanks in advance.
server {
listen 80 default_server;
root /var/www/html;
# Add index.php to the list if you are using PHP
index index.php index.html index.htm index.nginx-debian.html;
server_name _;
location ~* \.php$ {
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
try_files $fastcgi_script_name =404;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
set $path_info $fastcgi_path_info;
fastcgi_param PATH_INFO $path_info;
fastcgi_index index.php;
include fastcgi_params;
}
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404;
}
location ~* ^/(.+?)/www(/.*|/|)$ {
root /home;
index index.php index.html;
fastcgi_pass unix:/var/run/php5-fpm.sock;
# regex to split $uri to $fastcgi_script_name and $fastcgi_path
fastcgi_split_path_info ^(.+\.php)(/.+)$;
# Check that the PHP script exists before passing it
try_files $fastcgi_script_name =404;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
# Bypass the fact that try_files resets $fastcgi_path_info
# see: http://trac.nginx.org/nginx/ticket/321
set $path_info $fastcgi_path_info;
fastcgi_param PATH_INFO $path_info;
fastcgi_index index.php;
include fastcgi_params;
}
location ~* ^/(.+?)(/.*|/|)$ {
index index.php index.html;
try_files $uri $uri/ #home;
}
location #home {
rewrite ^/([^/]+?)$ /$1/www/ last;
rewrite ^/(.+?)(/.*|/)$ /$1/www$2 last;
}
}
The cons of this config, you can't use URI like /<anything_you_want>/www.
Maybe it helps. But it's weird, non-optimized and ugly config.
I don't know why my pages are not eachable without .php extension. Something is wrong ? However it work on another of my website
When I put try_files $uri $uri/ $uri.html $uri.php?$query_string; it's ok for the .php files without extension, but my website create "fakes folders/pages" like mywebsite.lol/category/example - and now it's doesn't reachable (404)
Here is my server{} block configuration.
# Gestion www
server {
# Port
listen 80;
# Hostname
server_name test.mywebsite.lol;
# Logs
access_log /var/log/nginx/test.mywebsite.lol.access.log;
error_log /var/log/nginx/test.mywebsite.lol.error.log;
root /home/mywebsite/www/test;
# Fichier a executer par defaut (en ordre)
index index.html index.php;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
# pass the PHP scripts to FastCGI server listening on the php-fpm socket
location ~ \.php$ {
try_files $uri =404;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
location ~ /\. {
deny all;
}
}
I have the following nginx server block in its configuration
server {
listen 80;
server_name mydomain.com;
location /deploy {
alias /home/somedir/deploy/;
}
# pass the PHP scripts to FastCGI server listening on /var/run/php5-fpm.sock
location ~ \.php$ {
try_files $uri =404;
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 to execute a php file at the url mydomain.com/deploy/erp/index.php or mydomain.com/deploy/erp
The above thing downloads the php file instead of executing it. I googled and found solutions that asks you to define a www directory or something. I just need to execute the file in a specific directory at specific url. What are my options?
You haven't told nginx what to do with .php files. Assuming you're using php-fpm, you'll need something like this:
server {
listen 80;
server_name mydomain.com;
root /home/somedir;
location / {
try_files $uri $uri/ =404;
}
location /deploy {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass 127.0.0.1:9000;
include fastcgi_params;
}
}