Nginx config for hosting two nested websites - nginx

I am trying to write a Nginx config so that:
If the URL is exactly /Site/ it must serve C:\Site\index.html
If the URL is /Site/something/else it must serve C:\Site\something\else (fallback to index.html if it doesn't exists) BUT only if /something/ is different from /api/ and /dev/
If the URL is /Site/api/something/else it must redirect the exact request to another server otherserver/api/something/else
If the URL is exactly /Site/dev/ it must serve C:\Site-Dev\index.html
If the URL is /Site/dev/something/else it must serve C:\Site-Dev\something\else (fallback to index.html if it doesn't exists) BUT only if /something/ is different from /api/
If the URL is /Site/dev/api/something/else it must redirect the exact request to another server otherserverdev/api/something/else
So the key point here is that:
/Site/ and /Site/dev are two different websites
Each one has its own .../api endpoint
So far I wrote this config:
server {
listen 19001;
include mime.types;
location ^~ /Site/api/ {
proxy_pass http://otherserver;
}
location ^~ /Site/dev/api/ {
proxy_pass http://otherserverdev;
}
location = /Site/ {
root C:\Site;
try_files /index.html =404;
}
location ~ ^/Site/(.*) {
root C:\Site;
try_files $1 $1/ /index.html =404;
}
location = /Site/dev/ {
root C:\Site-Dev;
try_files /index.html =404;
}
location ~ ^/Site/dev/(.*) {
root C:\Site-Dev;
try_files $1 $1/ /index.html =404;
}
}
This doesn't work at all, I'm getting index.html in every request and also dev and nondev are mixed up.
Is there a way to achieve what I need?

Related

Nginx proxy_pass for '/' route only, with $http_accept

The reasoning behind this is that if a client requests Content-Type: application/ld+json from the home page of my application then the query should be redirected to an API which will serve that. So, I have something like this:
location / {
if ($http_accept = 'application/ld+json') {
proxy_pass https://api.example.org/homepage_jsonld/;
}
root /var/www/example.org/dist;
try_files $uri $uri/ /index.html;
}
...which results in:
nginx: [emerg] "proxy_pass" cannot have URI part in location given by regular expression, or inside named location, or inside "if" statement, or inside "limit_except" block
Can anyone suggest how to get around this?
Ideally, I'd only need to use the proxy_pass if the route requested is '/', and to pass any other route on to the application in /var/www/example.org/dist.
The answer turns out to be as follows:
location = '/' {
if ($http_accept = 'application/ld+json') {
rewrite "^/" /homepage_jsonld break;
proxy_pass https://api.example.org;
}
root /var/www/example.org/dist;
try_files $uri $uri/ /index.html;
}
...in addition to the existing location / block.

What's wrong with Nginx location match rule

I do read the Nginx documentation about location matching.
I know about the prioriy of modifier.
And here is my config.
location = /login {
root /usr/share/nginx/mysite;
try_files $uri /index.html;
}
location = / {
root /usr/share/nginx/mysite;
try_files $uri /index.html;
}
location ~ /(.*) {
proxy_pass http://127.0.0.1:8080/$1;
}
What I want is when I type "http://example.com/" "http://example.com/login" , the request will goes index.html which is a React App , and other request will goes proxy pass to my Tomcat application which is bind 8080 port.
But "http://example.com/" "http://example.com/login" request goes proxy_pass , what?
According to Nginx documentation, the "=" modifier is "Priority one"
I expect it is an exact match.
If an exact match is found, the search terminates
I also use https://nginx.viraptor.info/ test for it.
It shows what I expected.
But it looks like the running server not act what Nginx doc said.
Any ideas?
The last parameter of a try_files statement is special. It can be a status code, a named location, or the URI of an internal redirect. See this document for details.
In your current configuration, Nginx generates an internal redirection to /index.html and restarts the search for a matching location. So the /index.html request is sent to the proxy_pass.
Place /index.html before the last parameter so that it's interpreted as a file parameter and is processed within the same location block. The $uri is unnecessary in this particular case.
For example:
root /usr/share/nginx/mysite;
location = /login {
try_files /index.html =404;
}
location = / {
try_files /index.html =404;
}
location / {
proxy_pass http://127.0.0.1:8080;
}
The =404 will never be reached. The final location can be simplified and the capture is unnecessary.

Getting 500 internal error on redirect rule of alias in nginx

I am newbie to nginx server. I am getting stuck in URL redirection. I have following lines to default file.
server {
listen 80;
root /home/ubuntu/web/server/current/public;
index index.php index.html index.htm index.nginx-debian.html;
server_name _;
error_log /home/ubuntu/web/error.log info;
location / {
# try_files $uri $uri/ /index.php?$query_string;
# try_files $uri $uri/ =404;
}
rewrite ^/web/(.*) /web/;
location /web/ {
alias /home/ubuntu/web/client/web/;
# try_files $uri $uri/ index.html;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
}
location ~ /\.ht {
deny all;
}
}
what I expect from above rewrite rule is - all URLs like - http://example.com/web/login, http://exmpale.com/web/dashboard will be redirected to /home/ubuntu/web/client/web/ and the default page to hit is index.html file.
When I open the error log file then i found error like -
rewrite or internal redirection cycle while internally redirecting to "/web/index.php", client: ip_address, server: _, request: "GET /web/ HTTP/1.1", host: "ipaddress"
What i am doing wrong here.
Answer credit goes to #RichardSmith, he provided possible error which is in right direction. I figure out my mistake in nginx rewriting rule.
rewrite ^/web/(.*) /web/;
location /web/ {
alias /home/ubuntu/web/client/web/;
# try_files $uri $uri/ index.html;
}
Instead of above I should have following-
rewrite ^/web/(.*) web/;
location web/ {
alias /home/ubuntu/web/client/web/;
# try_files $uri $uri/ index.html;
}
Server consider path as absolute whenever / placed before web. Thus rewrite statement tries to redirect to fallback file which is not existed in absolute path. Eventually, rewrite statement makes never ending loop.

Vanilla Forums sitemapindex.xml file inaccessible by nginx

My forum is installed on the url: example.com/forums
I have used nginx and Vanilla to "prettify" the urls. I've set
/forum/conf/config.php, “RewriteUrls” to “True”.
and in my nginx.conf:
location /forums {
index index.php index.htm index.html;
location ~* ^.+.(jpg|jpeg|gif|css|png|js|ico|xml)$ {
access_log off;
log_not_found off;
expires 30d;
}
try_files $uri $uri/ #forums;
}
location #forums {
rewrite ^/forums(.+)$ /forums/index.php?p=$1 last;
}
The problem is I installed the sitemap plugin by Vanilla Forums.
and the resulting sitemap is supposed to be located at
example.com/forums/sitemapindex.xml
But when I navigate there nginx gives me a 404.
How do I solve this?
The problem is that the URI /forums/sitemapindex.xml is being processed by the location ~* ^.+.(jpg|jpeg|gif|css|png|js|ico|xml)$ block and not being forwarded to /forums/index.php.
If you do not serve static .xml files, you could simply remove the |xml term from the regular expression.
Otherwise, you will need to make that URI a special case, for example:
location = /forums/sitemapindex.xml {
rewrite ^ /forums/index.php?p=/sitemapindex.xml last;
}

Nginx Proxy_pass try_files drop to location handler

I'm running into small hick up with try_files in combination with proxy_pass (or alias for that matter).
Current config:
location /staticsrv {
alias /var/www/static/trunk/;
#proxy_pass http://static.localtest.nl/;
}
location ~ ^/staticsrv/images/gallery/(.*)$ {
try_files $uri #img_proxy;
}
location #img_proxy {
rewrite ^(.*)$ /index.php/?c=media&m=index&imag=$uri;
}
However for every file it gets dropped to the rewrite rule as it doesn't exist.
Is there a "trick" (read correct config) to fix my misfortune? Or is it just not possible? Both domains will eventually be on the same server so we can work with alias and proxy_pass.
Thanks in advance
Your location ~ ^/staticsrv/images/gallery/(.*)$ needs a root or an alias to construct a local path for try_files to try. Also, you do not necessarily need a regular expression here:
location /staticsrv/images/gallery/ {
alias /var/www/static/trunk/images/gallery/;
try_files $uri #img_proxy;
}
location #img_proxy {
rewrite ^ /index.php/?c=media&m=index&imag=$uri last;
}
proxy_pass will not work with try_files as one deals with remote content and the other with local content.
I try to avoid using alias and try_files in the same location block because of this open bug.
A possible work around would be to use another intermediate URI that closely matches the document root:
location /staticsrv/images/gallery/ {
rewrite ^/staticsrv(.+)$ /trunk$1 last;
}
location /trunk {
internal;
root /var/www/static;
try_files $uri #img_proxy;
}
location #img_proxy {
rewrite ^ /index.php/?c=media&m=index&imag=$uri last;
}

Resources