Nginx + rewrite + php-fpm = confusion - nginx

I'm moving from Apache to Nginx. I've got problem with converting Apache rewrite rules into nginx rules. What I'm trying to convert:
RewriteRule ^$ www/controller.php?_url_=index [QSA,L]
RewriteRule ^/+$ www/controller.php?_url_=index [QSA,L]
RewriteRule ^([a-zA-Z0-9_]+)(/([a-zA-Z0-9_/]*))?$ www/controller.php?_url_=$1&_req_=$2 [QSA,L]
RewriteRule ^([a-zA-Z0-9/]+)controller.php?(.*)$ www/controller.php?$2 [QSA,L]
What I tried to use:
rewrite ^/$ /www/controller.php?_url_=index break;
rewrite ^/+$ /www/controller.php?_url_=index break;
rewrite ^/([a-zA-Z0-9_]+)(/([a-zA-Z0-9_]*))?$ /www/controller.php?_url_=$1&_req_=$2 break;
rewrite ^/([a-zA-Z0-9/]+)controller.php?(.*)$ /www/controller.php?$2 break;
If I use above rules my browser is downloading php file (server is not executing it) - I guessed it's not being passed to PHP-FPM. Somewhere I found I should replace "break;" with "last;" like:
rewrite ^/$ /www/controller.php?_url_=index last;
After replacing this still I'm downloading php file from http://example.org, but when I visit http://example.org/login I get into infinite loop. I read nginx documentation and different examples (also here at StackOverflow) but sill I can't find correct configuration. Could somebody point me into the right direction?
Here is my whole config file:
server {
listen 80;
server_name 10.10.100.172;
error_log /var/log/nginx/example.com.error.log debug;
rewrite_log on;
location / {
root /var/www/webs;
index index.php index.html index.htm;
rewrite ^/$ /www/controller.php?_url_=index last;
rewrite ^/+$ /www/controller.php?_url_=index last;
rewrite ^/([a-zA-Z0-9_]+)(/([a-zA-Z0-9_]*))?$ /www/controller.php?_url_=$1&_req_=$2 last;
rewrite ^/([a-zA-Z0-9/]+)controller.php?(.*)$ /www/controller.php?$2 last;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
location ~ \.php$ {
root /var/www/webs;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
EDIT:
I moved rules outside location segment and used "break;" at the end of each rule. I can reach /www/controller.php?url=login&req=/ when I go to example.org/login/ - controller.php was responsible for infinite loop. When I try to reach example.org or example.org/ I'm downloading controller.php file - like it's not being passed to the PHP-FPM. Any guess?

I used above rules outside location segment and it works! I tried viewing my page in different browser and ecerything is fine. I always forget about removing cache..

Related

Prestashop 1.7.8.6 multistore nginx rewrite rules

I install the prestashop 1.7 as a multistore and write nginx rewrite rule as
location /shop-1/ {
rewrite ^/shop-1/(.*)$ /$1 last;
try_files $uri $uri/ /index.php?$args;
}
location /shop-2/ {
rewrite ^/shop-2/(.*)$ /$1 last;
try_files $uri $uri/ /index.php?$args;
}
I follow the nginx conf file from https://devdocs.prestashop.com/1.7/basics/installation/nginx/
Now the Q is Parent domain navigating correctly and showing images but multistore redirected corrected to http://example.com/{shop-1 or shop-2} but not showing the images on the multishop urls, getting nginx 404 error on multishop url but same image showing on a parent domain.
example:
http://example.com/shop-1/45-medium_default/skirt.jpg not showing the image
http://example.com/45-medium_default/skirt.jpg showing the image
To explain what happened here I need to refer to nginx request processing phases, a subject not many people actually understand correctly.
Here is a set of rewrite rules being executed at the NGX_HTTP_SERVER_REWRITE_PHASE:
rewrite ^/(\d)(-[\w-]+)?/.+\.jpg$ /img/p/$1/$1$2.jpg last;
rewrite ^/(\d)(\d)(-[\w-]+)?/.+\.jpg$ /img/p/$1/$2/$1$2$3.jpg last;
rewrite ^/(\d)(\d)(\d)(-[\w-]+)?/.+\.jpg$ /img/p/$1/$2/$3/$1$2$3$4.jpg last;
rewrite ^/(\d)(\d)(\d)(\d)(-[\w-]+)?/.+\.jpg$ /img/p/$1/$2/$3/$4/$1$2$3$4$5.jpg last;
rewrite ^/(\d)(\d)(\d)(\d)(\d)(-[\w-]+)?/.+\.jpg$ /img/p/$1/$2/$3/$4/$5/$1$2$3$4$5$6.jpg last;
rewrite ^/(\d)(\d)(\d)(\d)(\d)(\d)(-[\w-]+)?/.+\.jpg$ /img/p/$1/$2/$3/$4/$5/$6/$1$2$3$4$5$6$7.jpg last;
rewrite ^/(\d)(\d)(\d)(\d)(\d)(\d)(\d)(-[\w-]+)?/.+\.jpg$ /img/p/$1/$2/$3/$4/$5/$6/$7/$1$2$3$4$5$6$7$8.jpg last;
rewrite ^/(\d)(\d)(\d)(\d)(\d)(\d)(\d)(\d)(-[\w-]+)?/.+\.jpg$ /img/p/$1/$2/$3/$4/$5/$6/$7/$8/$1$2$3$4$5$6$7$8$9.jpg last;
rewrite ^/c/([\w.-]+)/.+\.jpg$ /img/c/$1.jpg last;
As you can see, none of them matches the /shop-1/45-medium_default/skirt.jpg request URI. So on the next turn, during the NGX_HTTP_FIND_CONFIG_PHASE your location /shop-1/ { ... } will be selected to handle the request. Next, after rewrite ^/shop-1/(.*)$ /$1 last; rule being executed, your request URI will be rewritten to /45-medium_default/skirt.jpg, and due to the used last flag on the rewrite directive the NGX_HTTP_FIND_CONFIG_PHASE will be executed again. However the NGX_HTTP_SERVER_REWRITE_PHASE won't be executed again, and a new URI won't be rewritten according to those rules. What you should do instead is to place a rewrite rule at the server level before the ruleset for rewriting image requests:
rewrite ^/(?:shop-1|shop-2)(/.*) $1;
... image URIs rewrite rules here
Note that I don't use last (or break) flag for this rule since the rewrite rules chain should not be terminated after this rewrite will be triggered. None of those two locations that you show in your question will be needed at all.

How do I properly add try_url or rewrite for a .html add?

So, coming from the Apache world I am new to configuring NGNIX more than just the root site. I have tried to use an Apache to NGNIX rewrite, but the output doesn't seem to render the pages correctly.
Original .htaccess code:
RewriteRule ^ https://%1%{REQUEST_URI} [L,NE,R=301]
RewriteRule ^([^\.]+)$ $1.html [NC,L]
The output doesn't seem to work after reloading the new configuration.
I have been trying different configurations under my location block trying to just add .html and end of the URI/URL. This is for a sub-directory called "wiki" just serving static HTML files.
Here's my current configuration under HTTPS:
root /var/www/html/;
index index.php index.html;
...
location ^~ /wiki/ {
try_files $uri $uri/ #rewrite;
}
location #rewrite {
rewrite ^(.+)/$ $1.html permanent;
}
The alias or path is /var/www/html/wiki
Please advise. I was able to get /wiki/index.html to render, but any other HTML files do not rewrite from wiki/product to product/product.html. I keep getting 404 errors.

root defaults to welcome to Nginx when using a "greedy" location

It seems like similar questions have been asked consistently on the site, but despite of browsing dozens of similar questions, none of the solutions seem to work for me.
When I go to mydomain.com, then nginx shows the default "welcome to nginx" page, however, when I visit mydomain.com/whatever/blablabla/whatever then Nginx sends the user to index.php?q=$uri which is the expected behavior.
So the problem only happens when visiting the actual root domain: mydomain.com.
This is my default file:
server {
listen 80;
location / {
include /etc/nginx/include/php;
index index.php;
root /var/www/mydomain.com/current/web;
}
location ~ /(.*)/? {
try_files $uri $uri/ /index.php?$uri;
}
}
Under that configuration, visiting mydomain.com defaults to "welcome to nginx" page, but mydomain.com/whatever is sent to index.php as expected.
When I tweak that to, something like:
location ~ /^(.*)/?$ {
try_files $uri $uri/ /index.php?$uri;
}
or
location ~ /^.*/? {
try_files $uri $uri/ /index.php?$uri;
}
then mydomain.com starts working again, but mydomain.com/whatever starts showing a 404 page. I've tried a bunch of different configurations, but none of the configurations I've tried seem to fully work as I expect.
Basically what I want is pass the whole URL to a front controller, to parse it and take actions depending on the contents of such URL.
If it helps, I want to mimic in Nginx this behavior from Apache:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php
I also have another virtual host:
server {
listen 0.0.0.0:443;
root /var/www/mydomain.com/current/web;
index index.html index.php;
fastcgi_param HTTPS on;
include /etc/nginx/include/ssl;
include /etc/nginx/include/php;
}

Pinnect's htaccess rules to nginx

so I've been playing around with the rules trying to transform them, the pinnect script's rules are:
Options +FollowSymLinks
IndexIgnore */*
RewriteEngine on
#RewriteBase /
# if a directory or a file exists, use it directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# otherwise forward it to index.php
RewriteRule . index.php
# fix for uploadify 302, 406 errors
SetEnvIfNoCase Content-Type "^multipart/form-data;" "MODSEC_NOPOSTBUFFERING=Do not buffer file uploads"
I have pinnect on pinnect/ on the server, however VB is running on the index for now,
I've tried
location /pinnect {
try_files $uri $uri/ /index.php;
}
And different variations of that, however let's say I go to the /install directory - it tries to redirect me to pinnect/forums.php(because of VB), if I try to go to index.php directly, an endless loop occurs, anyone could give me a hand with this?
EDIT:
So i've got this rule currently
location ~ ^/pinnect/index.php { try_files maintenance.html #index.php; }
location ~ ^/pinnect/ {
rewrite ^/pinnect$ /pinnect/index.php last;
rewrite ^/pinnect/$ /pinnect/index.php last;
#rewrite ^/pinnect/([^.]+)$ /pinnect/index.php/$1 last;
rewrite ^/pinnect/(.*) /pinnect/index.php/$1 last;
}
However where ever I go, I get a 301, 302 so it's not behaving same way as the htaccess, could anyone help?
If it's just a matter of status code returned, you might have to use return instruction on your location block.
location ~ ^/pinnect/index.php { try_files maintenance.html #index.php; }
location ~ ^/pinnect/ {
rewrite ^/pinnect$ /pinnect/index.php last;
rewrite ^/pinnect/$ /pinnect/index.php last;
#rewrite ^/pinnect/([^.]+)$ /pinnect/index.php/$1 last;
rewrite ^/pinnect/(.*) /pinnect/index.php/$1 last;
return 200;
}
Read more…
As we are here, you should replace last by break since you have your instructions in a location block.
Also, you might prefer using ? instead of (.*) to drop the original arguments.
Read more…

WordPress 3.0 & nginx - permalink, 404 problem

I've installed nginx, FastCGI and PHP on my server. WordPress 3.0 installed after a bit of a monster battle, but it's installed and working well.
However, when I change the permalink settings to anything other than default, I get 404 errors on every post, article and page.
I understand that this is something to do with nginx not supporting .htaccess and WordPress getting confused with where to go when a page is requsted.
I've tried a few rewrites in the nginx conf files and even the nginx compatibility plugin; neither have worked. With one rewrite I managed to stop the 404 errors, but instead of WordPress finding the post I was after I merely got my PHP confirmation page. Bah.
Forums are littered with people with similar issues. Does anyone have a solution?
On your location / block,
add this and remove any non-specific rewrite rules:
try_files $uri $uri/ /index.php;
If wordpress is on another directory besides the root, instead of having
if (!-e $request_filename) {
rewrite ^/wordpress/(.+)$ /wordpress/index.php?q=$1 last;
}
You can have:
location /wordpress {
try_files $uri $uri/ /wordpress/index.php?$args;
}
This page has exactly the same concept. I should have read and tried it first: nginx rewrite rule under a subdirectory
After much pain:
# if filename doesn't exist, take the request and pass to wordpress as a paramater
if (!-e $request_filename) {
rewrite ^/wordpress/(.+)$ /wordpress/index.php?q=$1 last;
}
If the requested file does not exist, pass it to index.php. It's a bit slow and I think I might try and not use a query, but it does work... :)
Have you tried the nginx Compatibility plugin?
Plus ElasticDog seems to provide a fairly concise article on getting WP working with nginx - which includes getting pretty permalinks to work.
Here's another article that seems to deal specifically with nginx rewrite rules for WordPress.
This was how I solved my permalinks in my wordpress blogs in dreamhost.
Inside the folder /home/ftpusername/nginx/example.com/ (if you don't have it, create it)
created the file
nginx.conf with the following content
location / {
index index.php index.html index.htm;
try_files $uri $uri/ /index.php?$args;
}
restarted the nginx
/etc/init.d/nginx reload
Some notes:
ftpusername and example.com MUST be changed according to your system.
That was it!
Good luck for u all.
this does not work if you are using location other than / like:
~ .php$, what i meant to say that pretty link will work but your graphics will be all over the place. so what you need is exactly stated below.
http://www.pearlin.info
location ~ \.php$
{
try_files $uri $uri/ /index.php?$uri&$args;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
if (!-e $request_filename){
rewrite ^(.*)$ /index.php?url=$1 break;
}
I did the following..
in the folder
/home/userrunningnginx/nginx/domain.com
I have:
default.conf (file)
include /home/neukbaarofnietps/nginx/neukbaarofniet.com/drop;
drop (file)
# Rather than just denying .ht* in the config, why not deny
# access to all .invisible files
location ~ /\. { deny all; access_log off; log_not_found off; }
nginx.conf (file)
location / {
index index.php index.html index.htm;
try_files $uri $uri/ /index.php?$args;
}
WORDPRESS-NGINX.CONF (file)
#######################
# WP Super Cache
# if the requested file exists, return it immediately
if (-f $request_filename) {
break;
}
set $supercache_file '';
set $supercache_uri $request_uri;
if ($request_method = POST) {
set $supercache_uri '';
}
# Using pretty permalinks, so bypass the cache for any query string
if ($query_string) {
set $supercache_uri '';
}
if ($http_cookie ~* "comment_author_|wordpress|wp-postpass_" ) {
set $supercache_uri '';
}
# if we haven't bypassed the cache, specify our supercache file
if ($supercache_uri ~ ^(.+)$) {
set $supercache_file /wp-content/cache/supercache/$http_host$1/index.html;
}
# only rewrite to the supercache file if it actually exists
if (-f $document_root$supercache_file) {
rewrite ^(.*)$ $supercache_file break;
}
# all other requests go to Wordpress
if (!-e $request_filename) {
rewrite ^.*$ /index.php last;
}
Adding this block to your nginx.conf should solve the issue:
if (!-e $request_filename) {
rewrite ^/wordpress_dir/(.+)$ /wordpress_dir/index.php?q=$1 last;
}
Hope this helps.
Good luck.

Resources