Redirect everything but few pages in Nginx - nginx

I have a subdomain leading to website hosted in subfolder containing :
a subfolder named r, inside of which I have my CSS and other resources files (you'll understand why I have this folder later)
few files such as privacy-policy.php, imprint.php,...
a script index.php
I want that the user type http://www.example.com/STRING, he got served http://www.example.com/index.php?code=STRING except when this would lead to an existing page when adding back the .php(i.e. http://www.example.com/privacy-policy, http://www.example.com/imprint)
Right now, my nginx conf file gives this
location /subfolder/ {
try_files $uri $uri/ $uri.php index.php?code=$uri;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
location /subfolder/r/ {
try_files $uri $uri/ =404;
}
}
The subfolder r has been created so that the static files are not processed by PHP.
This works well for the static files inside the r subfolder, also works well for the imprint.php type, but it does not work for the redirect to index.php?code=$uri.
Why is that?

Related

Nginx load subpath as wordpress root

I'm trying to set up a Wordpress in a system that has another php application installed, using nginx as web server.
I've simplified my config file to the maximun. The following confi is serving one post of my blog:
server {
listen 80;
server_name blog.ct.com;
root /home/ff/www/blog/;
index index.php index.html;
location / {
try_files $uri $uri/ /index.php?$uri&$args =405;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_buffer_size 128k;
fastcgi_buffers 64 32k;
fastcgi_busy_buffers_size 128k;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
include /etc/nginx/fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param APPLICATION_ENV development;
fastcgi_param HTTP_X_FORWARDED_PROTO https;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
}
}
But, due my system's requirements I need to serve the blog from within a sub path (In my final system http://blog.ct.com/ should be serving my custom php app and http://blog.ct.com/vendor should be serving the wordpress blog).
The local root directory from wordpress must be /home/ff/www/blog/ (this cannot be changed, while my custom app's directory is /home/ff/www/myapp/). So I think I need to reserve location / for my custom app, I have to create a location /vendor
If I add /vendor and I return 403 in / (just to debug easier), the browser says 405 (notice the =405 in /vendor, also to debug easier):
location /vendor {
try_files $uri $uri/ /index.php?$uri&$args =405;
}
location / {
return 403;
}
So I think nginx is going into location /vendor but is not finding my php script in /home/ff/www/blog/index.php so its returning the fallback 405.
Any idea why this could happen?
How can I achieve to load http://blog.ct.com/vendor as the root from wordpress but keeping http://blog.ct.com/ using another php script?
I've found out the following hints that gave me the clue to fix the problem (in case someone has the same problem than me, this may help)
Using location /path is not the same as using location ~(/path) (regex have different priority, so maybe they are not being checked in the order you think)
Adding error_log /your/path/log/error.log debug; to any location block may help you to see how is nginx serving every request (e.g. to location fastcgi, location \vendor, or the server{ block).
alias /var/www/path/vendor works different than root /var/www/path/vendor (check Nginx -- static file serving confusion with root & alias);
In case of the root directive, full path is appended to the root including the location part, whereas in case of the alias directive, only the portion of the path NOT including the location part is appended to the alias.
using rewrite with alias can help you parse the php file you want independent of the path
if (!-f $request_filename) {
rewrite ^ $document_root/index-wp.php last;
}
Take care of the SCRIPT_FILENAME you are using (check it with error_log, see above), maybe you need fastcgi_param SCRIPT_FILENAME $fastcgi_script_name; but you are loading fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; so depending on your previous config you may be attaching the document root twice.
Two different configurations for fastcgi can be used if you change your index.php file names. E.g. location ~ wp\.php$ { will work with wp.php while location ~ \.php$ { will work with all other php files like index.php.

Nginx rewrite to make a "personal URL"

I'd like to be able to make "personal URL" for our users (Facebook like), which is of course a dynamic strings. it needs to be in the root of the site, and that is why I'm having a big headache with it.
The requirements that I have are:
1. I need
www.example.com/John.Doe (it can be a-zA-Z0-9_-.)
and rewrite it to:
www.example.com/profile?id=John.Doe
2. I also need the site scripts to be extension less like (which I was able to do, with the great people here, using "$uri.php$is_args$query_string;"):
so
www.example.com/login
will go to:
www.example.com/login.php
I tried a lot of things, but I just can't get the right formula to make it work.
This is my configuration, right now:
location / {
try_files $uri $uri/ $uri.php$is_args$query_string;
}
location ~ \.php$ {
if ($request_uri ~ ^/([^?]*)\.php(\?.*)?$) {
return 301 /$1$2;
}
try_files $uri =404;
include /etc/nginx/fastcgi_params;
fastcgi_pass 127.0.0.1:9001;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
You have an overlapping namespace for your extension-less scripts and your personal URLs, so you need to test for the presence of the $uri.php file before rewriting it to profile.php.
So rather than rewrite the URI in the first try_files directive (as you have it now), it may be better to use a named location block to process the PHP file without having to rewrite it first.
Like this:
location / {
try_files $uri $uri/ #php;
}
location #php {
try_files $uri.php #rewrite;
include /etc/nginx/fastcgi_params;
fastcgi_pass 127.0.0.1:9001;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
location #rewrite {
rewrite ^/([a-zA-Z0-9_.-]+)$ /profile.php?id=$1 last;
}
location ~ \.php$ {
if ($request_uri ...) { ... }
try_files $uri =404;
include /etc/nginx/fastcgi_params;
fastcgi_pass 127.0.0.1:9001;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
The first block serves static files. The second block processes extension-less PHP files (if and only if they exists). The third block performs a rewrite to profile.php (which does not need to be extension-less, as it is not exposed to the client). The fourth block processes normal .php URIs and includes your $request_uri fix.
Note that fastcgi_index is redundant in both this and the original configuration.
For more details, here are some links to the nginx documentation for the location, try_files and rewrite directives.

Different url rewriting according to locations

I really don't find any documentation I find clear about URL rewriting (I can't understand it, as I unexpectedly find the documentation really hard to read for a non-native).
I'm looking for a way to rewrite all routes that matches /*\.(js|png|jpg|css|ttf|xml)$/ toward path/media/ and try existance of file then return it if exists, else 404 not found
then if it begins with /ajax/ redirect all of it toward path/ajax/index.php
else redirect all of it toward path/www/index.php
I don't quite understand how I should do it, for now I created 3 locations /media/, /ajax/ and /www/ but I don't know if it is the right way to use rewrite and not return, or are the locations the correct way to do it.
I don't really understand what I've written in my sites-enabled/file regarding fastcgi. is this a interpretor path ?
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
If I get it right, it means "if it ends with .php, and it exists in hierarchy, then execute it".
And I don't know if I should put that kind of stuff for each location that has to deal with php (/www/ and /ajax/), especially since I'm going to do some routing for both. Moreover, I don't know if it should be done that way.
The simplest PHP configurations use a common root directive which is inherited by the location blocks, and in your case would be:
root path;
This means that /www/index.php and /ajax/index.php are both processed by the location ~ \.php$ block.
The default action can be defined by the try_files directive within a location / block:
location / {
try_files $uri $uri/ /www/index.php;
}
If you need a different default action for URIs which begin with /ajax, add a more specific location:
location /ajax {
try_files $uri $uri/ /ajax/index.php;
}
If you do not want your media URIs to begin with /media you can override the root for one specific location:
location ~* \.(js|png|jpg|css|ttf|xml)$ {
root path/media;
}
The fastcgi_split_path_info and fastcgi_index directives are unnecessary in your specific case. The include fastcgi_params; statement should be placed before any fastcgi_param directive to avoid the latter being inadvertently overridden:
location ~ \.php$ {
try_files $uri =404;
include fastcgi_params;
fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
See the nginx documentation for details.

Laravel and WordPress integration routing using nginx

I am developing web app in Laravel 5.2. I have existing WordPress site. So, I want to integrate Laravel with WordPress. WordPress app has static pages. I have two separate directories for Laravel and WordPress in my root directory.
laraApp
wpApp
I want to make wpApp as default app. So when user clicks login button, user will be redirected to laraApp. I want wpApp at www.example.com and laraApp in www.example.com/laraApp. I have nginx web server running. So what should be my nginx config file?
Current nginx config file is :
server {
listen 80;
root /var/www/root/wpApp;
index index.php index.html index.htm;
server_name www.example.com;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
# rewrite rules for laravel routes
location /laraApp {
rewrite ^/laraApp/(.*)$ /laraApp/public/index.php?$1 last;
}
location ~ \.php$ {
try_files $uri /index.php =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/run/php/php7.0-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
Here my Laravel app is accessible using url www.example.com/laraApp/public/
I want to access it using www.example.com/laraApp.
Thanks.
The configuration would be simpler if the base URI for each of the applications did not overlap. But given the constraints of your question, you must use two distinct document roots for the PHP section of each of the applications in your configuration.
As you have placed one of your applications in /, the other application is kept separate by the use of nested location blocks. Notice the use of the ^~ modifier to prevent the first PHP block from processing Laravel requests.
index index.php index.html index.htm;
root /var/www/root/wpApp;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
try_files $uri /index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass unix:/run/php/php7.0-fpm.sock;
}
location ^~ /laraApp {
rewrite ^/laraApp(.*)$ /laraApp/public$1 last;
}
location ^~ /laraApp/public {
root /var/www/root;
try_files $uri $uri/ /laraApp/public/index.php?$query_string;
location ~ \.php$ {
try_files $uri /laraApp/public/index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass unix:/run/php/php7.0-fpm.sock;
}
}
I am away from my test system at the moment so the above has not been syntax checked or tested.

How to install one site inside another with Nginx

I have a wordpress multisite on centos 6.5 at /var/www/html/site1
accessible at site1.com and everything there is fine.
I would like to install a single site called site2 at
/var/www/html/site2 but
accessible at site1.com/site2
The .conf for site1 has a server block like this:
location / {
try_files $uri $uri/ /index.php?$args;
}
#editing here to...
location /site2 {
root /var/www/html/site2/;
index index.php index.html index.htm;
try_files /index.html /index.php $uri $uri/;
}
location ~ /site2/(.*\.php)$ {
root /var/www/html/site2/;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$1;
include /etc/nginx/fastcgi_params;
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include /etc/nginx/fastcgi_params;
}
}
#end editing.
When I use try files try_files /index.html /index.php $uri $uri/; it works.
When I use try_files try_files /index.php $uri $uri/; the browser downloads the file instead of displaying it.
The location block should do the trick as long as you define a new root for the location:
location /site2
{
root /var/www/html/site2;
#put your rewrite rules here
}
You have to make sure that your fastcgi (I assume you'r using php-fpm) configuration uses the new docroot as well.
I don't know wordpress very well, but I reckon you also have to configure the second site to be in a subdirectory called /site2, otherwise links might not work properly.

Resources