nginx proxy_pass configuration - nginx

I need to proxy a couple of urls to different hosts. Actually, I'm using the same host with different port to test my nginx configuration. This is my virtual host definition:
server {
listen 8081;
server_name domain.com;
location /Plasmid/ {
proxy_pass http://localhost:8000/Plasmid/;
}
location /_community/ {
proxy_pass http://localhost:8082/comments_api/ ;
}
location / {
# rewrite cq_user_authenticated===(.*)/(.*)/iuuid=(.*)/commenti.html$ /Plasmid/comments/legacy/$3/$1 ;
# rewrite querystring===(.*)$ /Plasmid/comments/legacy/$1 ;
# rewrite cq_user_authenticated===([^&]*)&/.*uuid=([^/]*) /comments_api/legacy/$2 ;
# rewrite userdetails(.*) /Plasmid/comments/user_details ;
root html;
index index.html index.htm;
}
}
Of course my hosts file has mapping for the domain.com
When I call the url: http://domain.com:8081/Plasmid/default/page/12 I get an http 404
If I remove the second location from my configuration:
location /_community/ {
proxy_pass http://localhost:8082/comments_api/ ;
}
I get the resource I want, but some part are missed since the are hosted on a different platform:
[error] 1033#0: *1 open() "/usr/local/Cellar/nginx/1.2.6/html/_community/content
How can I resolve this issue?

Do a little change:
location ^~ /Plasmid/ {
proxy_pass http://localhost:8000/Plasmid/;
}
location ^~ /_comunity/ {
proxy_pass http://localhost:8082/comments_api/;
Why is that? Because ^~ means starts with and when you request for page:
http://domain.com:8081/Plasmid/default/page/12
it fit to that rule. In your configuration you are using no mark and something like this:
location /anylocation
and it looks like your nginx prefer rule
location / {
than
location /Plasmid
and
location /_comunity
because it's using root directive and searching for _community/content in html folder (as you get in error message).
In other words ^~ has greater priority than no mark. One thing that could also help is to add break directive after each proxy_pass directive;

Related

Nginx with static index.html and reverse proxy

I'm trying to configure Nginx location for hours, not sure what I'm doing wrong:
server {
listen 80;
server_name test.myserver.com;
location = / {
root /www/;
}
location / {
proxy_pass http://192.168.0.170;
}
}
Nginx is running on OpenWRT router, inside /www/ there is only a index.html file. All other addresses should be proxied to an Arduino in 192.168.0.170.
I understand "location = /" rule should precede "location /". I'm avoiding creating a rule for any other address than "/", like /a, /b, /c, and go on.
With this code, I get a 404 from "/", as there is no index.html in 192.168.0.170. If I remove "location / { proxy_pass ...}", I could get index.html result from "/" address.
EDIT:
-Including a return 302 /blah; inside "location = /" block works fine, so the rule is being applied.
For anyone that drop here, the solution I've found:
server {
listen 80;
server_name test.myserver.com;
root /www/;
location = / { }
location /index.html { }
location / {
proxy_pass http://192.168.0.170;
}
}
Ugly, but it works. Maybe OpenWRT implementation (version 1.12.2) isn't as reliable a full distribution (current in 1.19.1 version).
In my example, just copied you configuration and did a little tweak, to match with a current configuration I use in my server.
Changed the listen to a default_server
Added root to the server block.
Added index index.html index.htm; line.
You can try the following configuration:
server {
listen 80 default_server;
root /www;
index index.html index.htm;
server_name test.myserver.com;
location / {
proxy_pass http://192.168.0.170;
}
}
After change your configuration test your server block file with command:
sudo nginx -t
If everything is okay, restart the nginx instance:
sudo nginx -s reload
After restart with success if you are trying access via browser, try using incognito mode in a new browser instance. (just for cache clean)

ember, nginx, reverse proxy

I have my app deployed to a file server here at:
http://example.com/my-team/my-app
We want our app to be facing at:
http://amazingapp.com
So far this is what I have on nginx
server {
listen 80;
server_name http://amazingapp.com;
location / {
proxy_pass http://example.com/my-team/my-app/;
}
}
This works for initial http://amazingapp.com but any subsequent requests http://amazingapp.com/post/1/comment/2 result in 404
Most of the ember deploy examples have the file being served from the same location as the web server, using try_files $uri $uri/ index.html So i don't believe i'm able to go down that path?
I've tried using regex on the location but that requires the proxy_pass to have parameters.
If you could point me in the right direction would be so grateful.
Thanks in advance!
Consider your config below
server {
listen 80;
server_name http://amazingapp.com;
location / {
proxy_pass http://example.com/my-team/my-app;
}
}
When you access http://amazingapp.com/abc your location / will cut abc out of it and append to proxy_pass. Making your url as http://example.com/my-team/my-appabc. Fix is quite simple, just add a trailing/` to your proxy_pass
server {
listen 80;
server_name http://amazingapp.com;
location / {
proxy_pass http://example.com/my-team/my-app/;
}
}

nginx proxy_pass removing base path

So I currently have a site at http://www.example.com and I would like that all requests from
http://www.example.com/api/v2/<anything>
to be proxied to
http://api.v2.com/<anything>
Note that http://api.v2.com does not have a base path.
My config:
server {
listen 80;
server_name www.example.com;
location /api/v2/ {
proxy_pass http://api.v2.com;
}
location / {
index index.html;
root /var/www/example.com/htdocs;
}
}
This way, however, the requests are being proxies to http://api.v2.com/api/v2/<anything> keeping the original path, and not http://api.v2.com/<anything>.
I've already noticed that:
location /api/v2 {
proxy_pass http://api.v2.com/api;
works as desired - http://api.v2.com/api/v2/<anything> proxies to http://api.v2.com/api/<anything>.
Is there a way to achieve the first behavior (that is , http://api.v2.com/api/v2/<anything> to http://api.v2.com/<anything>)? Do I have to use a rewrite? I know it it related to normalized URIs and that is expected, just would like to know if there's a way to do it.
If you want to remove the proxy path from resulting url to the server, either you should have the uri part in the proxy url, or you should specify the rewrite part.
In this specific case, it should be like as follows,
location /api/v2/ {
rewrite /api/v2/(.*) /$1 break;
proxy_pass http://api.v2.com/;
}
for more information visit nginx documentation https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass
If the proxy_pass directive is specified with a URI, then when a request is passed to the server, the part of a normalized request URI matching the location is replaced by a URI specified in the directive.
server {
listen 80;
server_name www.example.com;
location /api/v2/ {
proxy_pass http://api.v2.com/;
}
location / {
index index.html;
root /var/www/example.com/htdocs;
}
}
Source: http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass

Modify $request_uri in Nginx

I have multiple apps running on the Nginx server:
http://example.com/app1/ctrl/view
http://example.com/app2/ctrl/view
...
I would like to assign these apps DNS like so:
http://app1.example.com
http://app2.example.com
...
For that I've tried the following server block:
server {
listen 80;
server_name app1.example.com;
location / {
proxy_pass http://example.com/app1/$request_uri;
}
}
If a user is not logged in, my app would redirect to URI:
app1/ctrl/user/login?_next=/app/ctrl/view
Essentially $request_uri becomes (Note doubled app1 instance):
app1/app1/ctrl/user/login?_next=/app/ctrl/view
Is there a convenient way to modify $request_uri or a better method to get around this problem?
EDIT1
It seems I've solved my problem with the following server block:
server {
listen 80;
server_name app1.example.com;
location / {
set $new_request_uri $request_uri;
if ($request_uri ~ ^/app1/(.+)$) {
set $new_request_uri $1;
}
proxy_pass http://example.com/app1/$new_request_uri;
}
}
If someone knows a better (or proper "Nginx") way to do this please don't hesitate to post an answer.
EDIT2
Based on the comments I've also tried the following:
server {
listen 80;
server_name app1.example.com;
location / {
proxy_pass http://example.com/app1/;
proxy_redirect /app1/ /;
}
location ~ ^/app1/(.+)$ {
return 301 http://$server_name/$1;
}
}
This one looks better on screen, as it eliminates app1 instance in the $request_uri part completely, but you must have two location blocks.
EDIT3
The most efficient way to solve my problem apparently is as shown in this config:
server {
listen 80;
server_name app1.example.com;
location / {
proxy_pass http://example.com/app1/;
proxy_redirect /app1/ /;
}
location /app1/ {
rewrite ^/app1(.+) $1 permanent;
}
}
This is due to the fact, that Nginx always tries to match the longest prefix first and then (if ^~ modifier is not present) starts sequentially processing regexes until the first regex match is found. Essentially this means that all regexes are processed on every request, regardless if any of these find a match, therefore it's better to have regexes inside location directives.
You don't need to go complex way. Solution is much simpler
server {
listen 80;
server_name app1.example.com;
location / {
proxy_pass http://app1.example.com/app1/;
}
location /app1/ {
proxy_pass http://app1.example.com/app1/;
# or
# rewrite ^/app1(.+) $1 permanent;
}
}
Nginx will take care of adding /app1/ to request and strip it from Location header.
See proxy_redirect directive.

Nginx resolves the wrong route

I have an nginx-based configuration, where the root of the domain should lead to a static page (a splash page) and anything else should be proxied to an internally accessible machine. The configuration looks roughly as follows:
server {
listen 80;
location = / {
root /var/www;
}
location ~ / {
location /robots.txt {
root /var/www;
}
proxy_pass http://127.0.0.1:9091;
proxy_set_header Host $host;
}
}
The problem is that if the second block of code exists, the first one stops being taken into consideration. In other words, nginx starts looking for an index.html file on the 9091 instance, which does not exist. If the proxy_pass block is commented, then the first part goes into effect.
As far as the documentation is concerned, this should not be the case. If the root of my domain is called, Nginx should stop searching after the first block, since it is explicit. Yet, this is not the case.
What should be done here? I do not want to merge the splash page code, with the rest.
Your config looks very weird, but there is no indication that it shouldn't work as you seem to intend.
Perhaps you could try something like this? Else, please provide your full configuration (perhaps your cut-down example is missing something important that we should know about).
server {
listen 80;
root /var/www;
location = / {
}
location = /index.html {
}
location = /robots.txt {
}
location / {
proxy_pass http://127.0.0.1:9091;
proxy_set_header Host $host;
}
}
Try this:
Replace splash.html to your splash page filename.
# Set root directory for requests
root /var/www;
# Rewrite / to /splash.html
rewrite ^/$ /splash.html break;
location = /splash.html { }
location = /robots.txt { }
location ~* / {
proxy_pass http://127.0.0.1:9091;
proxy_set_header Host $host;
}
I guess you have index directive somewhere and this is how index is works.
It should be noted that using an index file causes an internal redirect, and the request can be processed in a different location.
Your first location matches, but then index module cause internal redirect to /index.html and request ends up in second location block.
I would write something like this:
server {
listen 80;
root /var/www;
location = /index.html {
}
location = /robots.txt {
}
location / {
proxy_pass http://127.0.0.1:9091;
proxy_set_header Host $host;
}
}

Resources