I have a home-made CMS, serving a site which I inherited. I'm not really familiar with nginx rewrite rules, although I could set up tiny URLs. Here is my relevant part of the configuration:
*location / {
index index.php index.html;
root /var/www/www.valami.hu;
try_files $uri $uri/ #seo;
}
location #seo {
rewrite ^/([a-z]+)$ /index.php?oldal=$1 last;
break;
}*
The problem is that the site has a blog which is located on blogspot.com and the stuff from the blog is taken from there. So what I need help with is a rule for this sort of URL:
http://www.valami.hu/index.php?oldal=blog&options=2012/01/some-title-here.html
So, it would be fine like:
http://www.valami.hu/blog/2012/01/some-title-here
The most important is the first rule should be work also as it is more frequently used.
This is actually trivial. Watch and learn!
location / {
try_files $uri $uri/ #site;
}
location #site {
rewrite ^/blog/(.+)$ /index.php?oldal=blog&options=$1 last;
rewrite ^(.+)$ /index.php?oldal=$1 last;
}
The order makes all the difference. You can also do it by removing the last flag and redirecting to /blog with the options query string parameter explicitely set. No if is needed.
well seems we only have 2 cases, the /blog and the non /blog, I'd write 2 location blocks
location ~ ^/blog/(.*) {
try_files $uri /index.php?oldal=blog&options=$1;
}
location ~ /(.*) {
try_files $uri /index.php?oldal=$1;
}
I would have used just / and $request_uri in the second location but that would put a preceeding / in olda1, if that wouldn't matter with you then i'd prefer that method, cause it doesn't involve regex.
About index index.php index.html; and root /var/www/www.valami.hu;, it's better if you move them to the server block instead of the location block, if possible of course.
Related
I was reading this page here https://help.sorryapp.com/en/articles/2783542-install-maintenance-pages-on-nginx that had a nifty idea of having a file present means nginx would route to a maintenance html page.
But then reading through the nginx docs it seems like if statements within the location block are not ideal, and instead to use try files. Whats the proper way to rewrite whats in the above to how nginx would like it? https://www.nginx.com/resources/wiki/start/topics/depth/ifisevil/
I assume is something like: but what about a rewrite?
try_files /my/file/path/maint.on
error_page 503 #maintenance_page;
location #maintenance_page {
rewrite ^(.*)$ /maintenance_page.html break;
?
UPDATE 1
this is my current config snippit, which happens to for some reason result in a 404 even through the maint.on file doesn't exist.
location / {
if (-f /opt/staytus/staytus/maint.on) {
return 503;
}
port_in_redirect off;
proxy_pass http://example.com:8787/;
}
error_page 503 #Performing-Maintenance;
location #Performing-Maintenance {
rewrite ^(.*)$ Performing-Maintenance.html break;
}
}
any thought on the issue?
As the same article states,
The only 100% safe things which may be done inside if in a location context are:
return ...;
rewrite ... last;
so the example you're found can be considered completely safe. (I'd say it is safe to use any directive from ngx_http_rewrite_module inside the if block which extends this list to break, return, rewrite and set). You can't do what you want with the try_files directive because it is requires at least one file argument before the last uri (or the name of named location or HTTP error code) argument which would be used if none of the files/directories from the list are actually exists. Well, I could imagine something like
location / {
try_files /maintenance.html #default;
}
location #default {
...
}
but you can't make it serving some location like
location = /maintenance.html {
...
}
, it would just return the contents of maintenance.html file. And if maintenance.html page would refer to some additional assets (like CSS, JS etc.) all user browser requests for that assets would lead to the maintenance.html contents (because that file exists and passed the try_files check). Just FYI, this directive
location / {
try_files $uri $uri/index.php =404;
}
...
location ~ \.php$ {
...
}
won't serve the $uri/index.php file through the PHP location handler (it just return its raw content), while this
location / {
index index.php;
try_files $uri $uri/ =404;
}
would.
However example you provided would have some performance impact (especially on the high-load servers) due to the extra stat kernel call made for every incoming request. I'd recommend this method of enabling maintenance mode with nginx.
I have developers who will be working on their local machines editing multiple Wordpress sites. I'd like to set up Nginx for them one time without the need for them to edit the config file in the future. Typically when Nginx is configured to host Wordpress, a location block such as this is included:
location / {
try_files $uri $uri/ /index.php$is_args$args;
} # End location
In our situation, each WP site will be in its own subdirectory. So when a developer needs to view a site, they'll go to a URL in their browser such as:
http://localhost/site1
http://localhost/site2
http://localhost/site3
What we would like is for the location directive above to include the subdirectories. As it is now, it only includes the root (http://localhost) and not the subs. I think this requires a wildcard or regex of some kind, but I'm not sure.
In other words, I think I'm looking for a location block like:
location /all-subdirectories {
try_files $uri $uri/ /whatever-subdirectory/index.php$is_args$args;
} # End location
Does this make sense or am I on the wrong track?
You could use a regular expression location to capture the first part of the URI, for example:
location ~ ^(/[^/]+) {
try_files $uri $uri/ $1/index.php?$args;
}
Or use a named location with one or more rewrite statements, for example:
location / {
try_files $uri $uri/ #rewrite;
}
location #rewrite {
rewrite ^(/[^/]+) $1/index.php last;
}
On my previous server that ran apache I had some htaccess rules that helped forward a certain pattern of URL's which were giving 404's to the fixed pattern.
Long time ago my URLS for my site were http://domainname/articlename and then I changed it to be http://domainname/category/articlename
Now the problem is the older links that google has are returning 404's and I want to intercept any URL that doesn't have a category and insert a fake category and then my wordpress installation can resolve the URL.
So I'm looking for a nginx solution to this problem which I presume will be in the config file somewhere that will take this URL
http://www.criticalhit.net/prey/ (which gives a 404)
and change it to
http://www.criticalhit.net/fixed/prey/
which then resolves properly.
Use a named location to perform the rewrite, although this simple rewrite can be accomplished efficiently using a return 301.
Place a regular expression location (after the PHP location block) to bypass excluded URLs. This does not need to include the static files which are served by the try_files statement.
For example:
root /path/to/root;
index index.php;
location / {
try_files $uri $uri/ #rewrite;
}
location #rewrite {
return 301 /category$request_uri;
}
location ~ \.php$ {
try_files $uri =404;
...
}
location ~ ^/(category|tags|feeds) {
try_files $uri $uri/ /index.php;
}
See this document for more.
I always seem to have problems with nginx configurations. My SPA is located at /mnt/q/app (pushstate is enabled) and the frontend root is located at client/public. Everything should be mapped to index.html, where the app picks up the route and decides what to do.
Full path to the index is /mnt/q/app/client/public/index.html.
I think I ran out of options by now. No matter what I do, I just get a 404 back from nginx, I think the configuration is simple enought and have no clue what's wrong.
server {
listen 80;
server_name app.dev;
root /mnt/q/app;
location / {
root /client/public;
try_files $uri #rewrites =404;
}
location #rewrites {
rewrite ^(.+)$ /index.html last;
}
}
Any help is appreciated.
If nginx views the file system from the root, then the root should be set to /mnt/q/app/client/public, and not either of the two values you are using.
The last element of the try_files directive can be a default action (e.g. /index.html), a named location or a response code. You have a named location in the penultimate element - which will be ignored.
Your named location should work, but is unnecessary, as try_files is capable of implementing it more simply. See this document for more.
For example:
root /mnt/q/app;
location / {
root /mnt/q/app/client/public;
try_files $uri $uri/ /index.html;
}
location /api {
}
location /auth {
}
The $uri/ element will add a trailing / to directories, so that the index directive can work - you do not have to add it if you do not need it.
Can someone help me for my nginx rewrite rule. I have the problem like this
if file not found in www.abc.com/name_dir/* it will redirect to www.abc.com/name_dir/index.php .
for example :
not found in www.abc.com/xxx/* redirect to www.abc.com/xxx/index.php
not found in www.abc.com/yyy/* redirect to www.abc.com/yyy/index.php
not found in www.abc.com/zzz/* redirect to www.abc.com/zzz/index.php
not found in www.abc.com/kk/* redirect to www.abc.com/kkk/index.php
...
the problem i have thousand of name_dir. I have nginx.conf like this
if (-f $request_filename) {
break;
}
if (-d $request_filename) {
rewrite (^.+$) $1/
break;
}
if (!-e $request_filename) {
rewrite ^/xxx/(.*)$ /xxx/index.php?$1 last;
rewrite ^.+?(/.*\.php)$ $1 last;
}
In configuration above only redirect name_dir xxx. How rewrite rule to redirect all directory ?
Thank for your help
You want to use try_files to check for the existence of files instead of if statements here (because If's are Evil in Nginx).
To to a single directory, it would be like:
location /xxx/{
try_files $uri $uri/ /xxx/index.php;
index index.php
}
What this does is try the uri as a file first. If that doesn't work, it'll try as a directory. If neither work, it'll default to index.php of /xxx/. The extra index line is to keep it from showing a blank page if you go directly to whatever.com/xxx
Using regex, we can expand this rule to work with more than one directory:
location ~* ^(/.*)/{
try_files $uri $uri/ $1/index.php?$uri&$args;
index index.php
}
This should grab the full directory structure and rout it to the appropriate index.
abc.com/yyy/nonexistant.php ==> abc.com/yyy/index.php
abc.com/yyy/zzz/nonexistant.php ==> abc.com/yyy/zzz/index.php
If you only wanted the second example to go to yyy/index.php, use this regex in the location instead:
^(/.*?)/