nginx not redirecting to upstream location - php

I thought I had understood the basics of nginx rewrite rules. How wrong I was.
Can you please let me know what is I am doing so wrong here:
server {
listen 80;
server_name myserver;
index index.php index.html index.htm;
root /apps/user/websites/;
location / {
autoindex on;
}
location ~ myapp {
try_files $uri $uri /office/myapp/api/public/index.php;
}
location ~\.php$ {
try_files $uri $uri /office/fake/index.html;
# include fastcgi.conf;
# fastcgi_pass php-fpm-upstream;
}
}
If I visit http://myserver/office The index.php is accessed, but instead of being caught by the last location (~.php$) as I thought it would, it is processed as a text file and send to the browser.
I was expecting to receive the office/fake/index.html file instead.
Thank you very much,
Andres

Regex matching locations are checked in the same order they are appeared in the config file. Having the
location ~ myapp {
try_files $uri $uri /office/myapp/api/public/index.php;
}
before the
location ~\.php$ {
try_files $uri $uri /office/fake/index.html;
# include fastcgi.conf;
# fastcgi_pass php-fpm-upstream;
}
would give you an endless loop on every URI containing myapp substring (except those that are matching existed files and not ended with .php) because the /office/myapp/api/public/index.php URI matches the myapp regex. You should swap those locations in order to get this configuration workable.

Related

Nginx multiple projects in one domain blank page laravel

This is my config here for Nginx. I have a domain named tstdmn and two Laravel projects first tstdmn.com project and second florist project I want to deploy florist project into the tstdmn.com/florist, I set it all but it returns a blank page at tstdmn.com/florist what's my issue here?! And I know the problem is with my Nginx configuration because I switch the florist project to the main project and it works, it's not from my Laravel configurations
root /var/www/html/tstdmn.com/public;
# Add index.php to the list if you are using PHP
index index.html index.php index.htm index.nginx-debian.html;
server_name tstdmn.com www.tstdmn.com;
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ /index.php?$query_string;
}
location ^~ /florist {
alias /var/www/html/florist/florist_backend/public;
try_files $uri $uri/ #laravel1;
location ~ \.php {
fastcgi_pass unix:/var/run/php/php7.1-fpm.sock;
fastcgi_split_path_info ^(.+\.php)(.*)$;
include /etc/nginx/fastcgi_params;
}
}
location #laravel1 {
rewrite /florist/(.*)$ /florist/index.php?/$1 last;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php7.1-fpm.sock;
}
And so another route of project show's blank like /register
I solved it by someone's solution at laracasts:
using subdomain instead of routing
server { listen 80; listen [::]:80;
root /var/www/html/florist/florist_backend/public;
# Add index.php to the list if you are using PHP
index index.html index.php index.htm index.nginx-debian.html;
server_name florist.tstdmn.com;
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ /index.php?$query_string;
}
..... and some code not related
address of question in laracast https://laracasts.com/discuss/channels/servers/nginx-multiple-projects-in-one-domain-errors

Directory Override with NGINX

I need a special directory override of NGINX rules on my web server so that the rules that apply to /var/www/acme regarding CSS, JS, etc. do not apply to /var/www/acme/special. I have a /var/www containing my website under me.com (127.0.0.1 localhost setup). Inside there, I have an acme folder that uses a special framework for my PHP. However, I have a folder /var/www/acme/special that needs to not apply those same rules and just run like a regular PHP website. I'm stuck because when I apply the logic with a special location and try_files routine, along with a break, for /var/www/acme/special, then I get an HTTP 500 error that says "rewrite or internal redirection cycle when internally redirecting to '/acme/special////////////".
Here's my /etc/nginx/sites-available/me.com file for NGINX on Ubuntu 16.04. What am I doing wrong?
server {
listen 80;
listen [::]:80;
root /var/www;
index index.php index.html;
server_name me.com www.me.com;
location /acme/special {
try_files $uri $uri/;
break;
}
location ~ ^/acme/(.*(?<!boot))/css/(.*)$ {
alias /var/www/acme/$1/views/assets/css/$2;
}
location ~ ^/acme/(.*(?<!boot))/js/(.*)$ {
alias /var/www/acme/$1/views/assets/js/$2;
}
location ~ ^/acme/(.*(?<!boot))/img/(.*)$ {
alias /var/www/acme/$1/views/assets/img/$2;
}
location ~ ^/acme/(.*)/fonts/(.*(?<!boot))$ {
alias /var/www/acme/$1/views/assets/fonts/$2;
}
location ~ ^/acme/(.*)/boot/(.*)$ {
alias /var/www/acme/$1/views/assets/boot/$2;
}
location / {
try_files $uri $uri/ #php;
}
location #php {
rewrite ^/acme/([^\/]+)/.*((?!index\.php).)*$ /acme/$1/index.php?query_string last;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php7.0-fpm.sock;
}
}
Try:
location /acme/special {
try_files $uri $uri/ =404;
}
The last parameter of the try_files statement is the default action, so the $uri/ term is not being treated as one of the file terms. Use =404 or something like /index.php depending on your desired file-not-found response. See this document for more.
The break is part of the rewrite module and has no purpose here.

Nginx to serve static page before dynamic

I want to serve static HTML files with NGINX, but if the file is missing, it should load a PHP file instead and PHP should handle the content.
I've been testing several combinations of try_files, but I can't get my head around it. I have a dummy PHP app that looks like this:
./
../
dynamic.php
index.php
static/
static/static.html
Then I have a small PHP code on index like this:
<?php
$path = $_SERVER['REQUEST_URI'];
$pattern = '/^\/(.*)\.html$/';
$matches = [];
$results = preg_match($pattern, $path, $matches);
if (count($matches) > 0) {
if ($matches[1] == "dynamic") {
require 'dynamic.php';
} else {
echo "Not found!";
}
} else {
echo "Index page!";
}
The results of browsing to each page should be:
http://foo.bar/ - Loads index.php
http://foo.bar/static.html - Loads static/static.html
http://foo.bar/dynamic.html - Loads index.php & PHP requires dynamic.php
http://foo.bar/baz.html - Loads index.php with "not found" message
This is what I got in the NGINX config file:
server {
listen 80;
server_name .foo.bar *.foo.bar;
access_log /var/log/nginx/foo.access.log;
error_log /var/log/nginx/foo.error.log;
root /var/www/foo;
index index.php;
location / {
# Trying with 'try_files' here. No success.
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php5-fpm-foo.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
I've been trying repeatedly and evidently utterly failing with this line:
try_files $uri $uri/static /index.php;
I am missing something. Help?
I would use your static directory as document root. This ensures that nobody can execute /dynamic.php directly, however, it will be forwarded to your index.php by the named location block #php.
This configuration example is untested!
server {
index index.php;
root /var/www/foo/static;
server_name foo.bar *.foo.bar;
location / {
try_files $uri #php;
}
location #php {
include fastcgi_params;
fastcgi_pass unix:/var/run/php5-fpm-foo.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /var/www/foo/index.php;
}
}
You don't need the listen directive if it only contains 80 since this is the default.
The server_names should not contain a leading dot.
The $uri always contains the requested URI including the leading slash (e.g. /static.html) and nginx will prefix them with the document root upon invocation of try_files (e.g. /var/www/foo/static.html). Hence, you need to set your static directory before the $uri (e.g. /static$uri becomes /var/www/foo/static/static.html).
You don't need fastcgi_split_path_info because you are not using that feature.
Your try_files in your PHP location makes it impossible for nginx to properly forward things. A request for /dynamic.html does not end on .php, hence, try_files always fails.
There are a number of ways of hiding the static directory from the URL. For example, manipulating root, clever use of try_files or a rewrite.
Possibly the most obvious is this:
root /var/www/foo;
location / {
root /var/www/foo/static;
try_files $uri /index.php;
}
location ~ \.php$ { ... }
so that nginx looks in the static folder for normal files, but the parent folder for .php files.
What you were trying to achieve was something like this:
root /var/www/foo;
location / {
try_files /static$uri /index.php;
}
location ~ \.php$ { ... }
which will prefix /static to any URI before testing for existence. The /index.php must be the last element as it required processing in a different location. See this document for more.
Based on the specific example case you have given, the configuration below will return the results you listed.
server {
listen 80;
server_name .foo.bar *.foo.bar;
access_log /var/log/nginx/foo.access.log;
error_log /var/log/nginx/foo.error.log;
root /var/www/foo;
index index.php;
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php5-fpm-foo.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
location ~ /static {
rewrite ^/static\.html$ /static/ last;
index static.html;
}
location ~ / {
rewrite ^ /index.php last;
}
That is ...
http://foo.bar/ - Loads index.php
http://foo.bar/static.html - Loads static/static.html
http://foo.bar/dynamic.html - Loads index.php & PHP requires dynamic.php
http://foo.bar/baz.html - Loads index.php with "not found" message

NGINX configuration for static and PHP files

I am trying to configure nginx to serve static and PHP files. The config I have isn't working. I want the following local folder structure:
src/static/ -> contains HTML, CSS, JS, images etc
src/api/ -> contains PHP files for a small REST service
If I visit http://mysite.local I want to be served files from the /static folder. If I visit http://mysite.local/api I want to be served the API PHP files. I want the requests to the api to be re-written and sent to an index.php file.
Some examples:
http://mysite.local/test.html -> served from src/static/test.html
http://mysite.local/images/something.png -> served from src/static/images/something.png
http://mysite.local/css/style.css -> served from src/static/css/style.css
http://mysite.local/api/users -> served from src/api/index.php?users
http://mysite.local/api/users/bob -> served from src/api/index.php?users/bob
http://mysite.local/api/biscuits/chocolate/10 -> served from src/api/index.php?biscuits/chocolate/10
The below config works for static files but not for the api files. I get a 404 error back if I visit one of the API paths.
server {
listen 80;
server_name mysite.local;
access_log /var/log/nginx/mysite.access.log main;
error_log /var/log/nginx/mysite.error.log debug;
location / {
index index.html;
root /var/www/mysite/src/static;
try_files $uri $uri/ =404;
}
location /api {
index index.php;
root /var/www/mysite/src/api;
try_files $uri $uri/ /index.php?$query_string;
location ~ \.php$ {
try_files $uri = 404;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
}
The initial problem is the root directive in the location /api block, which should not include the location component as this gets appended as part of the URI, so:
location /api {
root /var/www/mysite/src;
...
}
will result in a local path of /var/www/mysite/src/api/index.php when presented with the URI /api/index.php. See this document for details.
The try_files rule does not rewrite the URI as you specify in your example. If you really need the final path of the URI to be presented as a query string to /api/index.php you will need to use rewrite.
The simplest solution (if you do not need to serve static content from that location) is to replace your try_files with:
location /api {
...
rewrite ^/api/(.*)$ /api/index.php?$1 last;
location ~ \.php$ { ... }
}
Otherwise, use a named location:
location /api {
...
try_files $uri $uri/ #rewrite;
location ~ \.php$ { ... }
}
location #rewrite {
rewrite ^/api/(.*)$ /api/index.php?$1 last;
}
See this and this for details.

How to remove both .php and .html extensions from url using NGINX?

I want my nginx make display all url's clean.
http://www.mydomain.com/indexhtml.html as http://www.mydomain.com/indexhtml
http://www.mydomain.com/indexphp.php as http://www.mydomain.com/indexphp
With some research I've made the first case to work. It`s done by following configuration:
location / {
root html;
index index.html index.htm index.php;
try_files $uri.html $uri/ =404;
}
It works for indexhtml.html displaying as indexhtml, but nothing happens with .php. If I change $uri.html to $uri.php, it works neither for .html, neither .php. I`ve tried to put something similar in php location but without any success.
Any advices?
From what I've researched, if you append your /etc/nginx/conf.d/domain.tld.conf file to include:
location / {
try_files $uri $uri.html $uri/ #extensionless-php;
index index.html index.htm index.php;
}
location ~ \.php$ {
try_files $uri =404;
}
location #extensionless-php {
rewrite ^(.*)$ $1.php last;
}
Then restart nginx and give it a go. Hopefully this will help you! More information can be found (where I found it) here # tweaktalk.net
No need for extra blocks and named locations and everything. Also move the index line outside the location block
server {
index index.html index.php;
location / {
try_files $uri $uri/ $uri.html $uri.php$is_args$query_string;
}
location ~ \.php$ {
try_files $uri =404;
# add fastcgi_pass line here, depending if you use socket or port
}
}
Keep in mind that if you have a folder and a file with the same name inside the same folder, like /folder/xyz/ and /folder/xyz.php you won't be able to run the php file if the folder xyz contains an index.php or index.html, just keep this in mind.
To further Mohammad's answer, you might also want to offer redirects from .html and .php to the extensionless versions.
This can be accomplished due to the fact that $request_uri contains "full original request URI (with arguments)", and is not affected by the internal rewrites that are not visible to the user.
server {
index index.html index.php;
location / {
if ($request_uri ~ ^/(.*)\.html$) { return 302 /$1; }
try_files $uri $uri/ $uri.html $uri.php?$args;
}
location ~ \.php$ {
if ($request_uri ~ ^/([^?]*)\.php($|\?)) { return 302 /$1?$args; }
try_files $uri =404;
# add fastcgi_pass line here, depending if you use socket or port
}
}
This has worked for me for more than 5 years going.
location / {
try_files $uri/ $uri.html $uri.php$is_args$query_string;
}
Perhaps this may be of use for you... It' Simple and gets the job done:
location / {
rewrite ^/([^\.]+)$ /$1.html break;
}

Categories