Nginx: Setting a default file extension - nginx

What rule would I use for nginx so my default file extension is .php?
I currently access a pages using www.mywebsite.com/home.php but I want to just use www.mywebsite.com/home
Thanks

Assuming you also want to serve static files, you could use something like this:
server {
server_name example.com;
# Set the docroot directly in the server
root /var/www;
# Allow index.php or index.html as directory index files
index index.html index.php;
# See if a file or directory was requested first. If not, try the request as a php file.
location / {
try_files $uri $uri/ $uri.php?$args;
}
location ~ \.php$ {
# If the php file doesn't exist, don't pass the request to php, just return a 404
try_files $uri =404;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $request_filename;
fastcgi_pass your_php_backend_address;
}
}

Related

Nginx rewrite to prevent PHP file direct access

I'm trying to setup some rewrites so that
(1) .com/images/* will load naturally
(2) .com/* will be rewritten to .com/loader.php?control=*
However the code below works perfectly except it will execute .com/config.php instead of rewriting it to .com/loader.php?control=config.php
How can I prevent my rewrite being overridden? I only want .php files to be executed if it's loader.php or in the images folder. (Been trying for hours)
server {
listen 80;
root /mnt/web/test_com/public_html;
server_name test.com;
index index.html index.php index.htm;
location ~ .php(.*)$ {
fastcgi_pass unix:/tmp/php-70-cgi.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $DOCUMENT_ROOT$fastcgi_script_name;
fastcgi_param PATH_INFO $2;
include fcgi.conf;
}
location / {
rewrite ^/(.*)$ /loader.php?control=$1 last;
}
location /images/ {
}
}
Thanks!
You should look into the try_files directive
Like the return and rewrite directives, the try_files directive is placed in a server or location block. As parameters, it takes a list of one or more files and directories and a final URI
Read the whole blog-post written on the nginx blog here:
https://www.nginx.com/blog/creating-nginx-rewrite-rules/

Is $uri/ some kind of special syntax for Nginx?

If I have the following configuration, then request to / is downloading the index.php file directly from the server root(i.e., not passing to php-fpm).
server {
listen 127.0.0.1:8080;
root /home/hasib/playground/php/;
server_name test.test;
index index.php;
location / {
try_files $uri $uri/index.php =404;
}
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass unix:/run/php/php7.0-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
But, if I change the try_files line to this:
try_files $uri $uri/ =404;
then by requesting /, I'm getting the expected output of index.php file(i.e., processed output of php-fpm).
I have also tried to put folder name in try_files like this:
try_files $uri /myfolder/ =404;
but that is returning 301 redirect to /myfolder/ when requesting for /, instead of trying the index.php file under myfolder directory.
So, my question is, is $uri/ some kind of special syntax for Nginx? As the other configurations always serves the files directly or redirects to myfolder. But by including $uri/ it tries to pass the index.php file to php-fpm.
Your first example is invalid. The .php file needs to be processed in another location and therefore must be the last parameter of the try_files statement. See this document for more.
Any file parameter that ends in / will check for the existence of a directory, so $uri/ is not special, but the trailing / is. This is used to invoke index processing. See this document for more.

Nginx alias directive not working with php

I have an app that is running on Nginx with a working server block like so:
server {
listen 80;
server_name example.com;
root /home/deployer/apps/my_app/current/;
index index.php;
location / {
index index.php;
try_files $uri $uri/;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/home/deployer/apps/shared/php5-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
}
location /foo {
root /home/deployer/apps/modules/;
# tried this:
# alias /home/deployer/apps/modules/foo/;
# but php is not working with alias, only with root
}
}
When I visit /foo, Nginx looks in the path /home/deployer/apps/modules/foo/ for an index.php file and it works.
The problem:
I set up a deploy script using capistrano that deploys to the foo directory:
/home/deployer/apps/modules/foo/
Capistrano creates a 'current' directory within the 'foo' directory to contain the application files pulled in from Github, so I needed to change the root path to be:
/home/deployer/apps/modules/foo/current/
But Nginx appends the location directive to the end of the root directive.... so, when you visit /foo, Nginx tries to look in:
/home/deployer/apps/modules/foo/current/foo/
Using alias is supposed to disregard the /foo set in the location directive and serve files from the exact alias path (which the logs confirm is happening), but when I use the alias directive, the php configuration is not being applied correctly and I am getting a 404 returned.
If I go back to the root directive and remove the 'current' directory altogether, it works fine. I need the files to be served from the 'current' directory to work smoothly with the Capistrano deploy, but cannot figure out how to make the alias directive work with php.
Anyone have any ideas or advice, am I missing something?
thanks to #xavier-lucas for the suggestion about not being able to use try_files with alias.
To use alias with php, I had to remove the try_files directive from the php location block shown in the original question:
try_files $uri =404;
I actually had to restate the php location block within the /foo location and remove the above line. It ended up looking like this:
location /foo {
alias /home/deployer/apps/modules/foo/;
location ~ \.php$ {
# try_files $uri =404; -- removed this line
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/home/deployer/apps/shared/php5-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
}
}
This allows php files to be processed directly from the directory listed in the alias directive.
Use
location /foo/ {
alias /home/deployer/apps/modules/foo/current/;
}
instead of
location /foo {
alias /home/deployer/apps/modules/foo/;
}

Nginx sites-available doesn't work

I've got this really simple server block under sites-available.
Problem: When I try to access to mydomain.com, Nginx returns a « 404 Not Found », but if I try to access to a file in particular, it works fine, like mydomain.com/index.php
server {
listen 80;
index index.php;
server_name mydomain.com;
root /home/myusername/sites/mydomain.com/htdocs;
access_log /home/myusername/sites/mydomain.com/logs/access.log;
error_log /home/myusername/sites/mydomain.com/logs/error.log;
location / {
try_files $uri =404;
}
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
}
}
Note that:
my hosts file is configured ;
I restart Nginx after each edit ;
the access rights, user and group are correct ;
the error.log file is empty, the access.log returns me all the 404 ;
I tried to change the config by adding/removing some lines, still no changes ;
the site is enabled in sites-enabled with a correct symlink (I tried to edit it and it opened the right file) ;
I've got a few sites on the same server who runs well (so the including of sites-available and sites-enabled is OK, and Nginx works fine).
So, the answer was giver to me on ServerFault by Alexey Ten, here is a copy of the answer
Your try_files directive is too restrictive and, I guess, is in wrong place.
Either remove location / completely, it doesn't makes much sense, or, at least add $uri/ so index directive will work.
try_files $uri $uri/ =404;
But my guess is, you need to move this try_files into location ~ \.php$, this will make sure that php-file exsists before pass it to PHP-FPM for processing. All other files will be served by nginx with proper use of index directive.
server {
listen 80;
index index.php;
server_name mydomain.com;
root /home/myusername/sites/mydomain.com/htdocs;
access_log /home/myusername/sites/mydomain.com/logs/access.log;
error_log /home/myusername/sites/mydomain.com/logs/error.log;
location ~ \.php$ {
try_files $uri =404;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
}
}

How to retrieve directory used in try_files directive?

I have a hard time figuring out how try_files directive work.
This configuration works as expected if index file is used (http://domain.com/):
X-Fcgi-Script-Name /main_apps/domain.com/index.php
X-Script-Filename /var/www/main_apps/domain.com/index.php
However if I specify PHP script (index.php or other) try_files find file as expected, but take a look at variables:
X-Fcgi-Script-Name /index.php
X-Script-Filename /var/www/index.php
So my question is: How can I find which directory was picked by try_files directive?
Used server configuration:
server {
server_name ~^(?P<domain>.+)$;
root /var/www;
autoindex off;
index index.php;
try_files /main_apps/$domain$uri/ /partners/$domain$uri/ =404;
more_set_headers "X-Script-Filename: $request_filename";
more_set_headers "X-Fcgi-Script-Name: $fastcgi_script_name";
# Pass PHP scripts to PHP-FPM
location ~ \.php$ {
fastcgi_param SCRIPT_FILENAME $request_filename;
include php_fpm_params;
}
}
Note: Nginx I use is compiled with 3rd party module HeadersMore.
However if I specify PHP script (index.php or other) try_files find file as expected
You're wrong here. In this case your request handled by location ~ \.php$ where no try_files.
btw, server_name ~^(?P<domain>.+)$; is overkill. You should use $host variable.

Resources