Nginx redirecting traffic to a reserve server - nginx

I have an Nginx server. Which distributes traffic to multiple servers, below is the config:
location /rc/temp/ {
proxy_pass https://rc1-test.jer.com;
}
location /rc/ {
if ($testip) {
proxy_pass http://192.168.0.100;
}
proxy_pass http://192.168.0.103;
}
location / {
if ($is) {
proxy_pass https://rc6-test.jer.com;
}
proxy_pass https://rc8-test.jer.com;
}
I want to know if it is possible to add some if ...else so that there would be an opportunity, for example, if some one with the server is unavailable, then the traffic is redirected to the reserve. For example, for location /rc/temp/ if https://rc1-test.jer.com is not available; then direct traffic to a clone of this server https://rc2-test.jer.com;. Thanks.

Try error_page directive:
location /rc/temp/ {
proxy_pass https://rc1-test.jer.com;
error_page 500 #fallback
}
location #fallback {
proxy_pass https://rc2-test.jer.com;
}
You may change the 500 code in the error_page directive with some other error code if you need to.

Related

What is the proper way to handle complex reverse proxy rules in GCP?

I have the following NGINX config that works and is hosted in a K8s cluster...
server {
listen 80;
server_name me.com;
location /identity {
proxy_pass https://cloud-function-id.uc.gateway.dev/environment;
proxy_ssl_server_name on;
proxy_ssl_name $proxy_host;
}
location /assets {
proxy_pass http://BUCKET_IP;
}
location / {
try_files $uri $uri/ /index.html;
}
location = / {
proxy_pass http://BUCKET_IP/index.html;
}
location = /index.html {
proxy_pass http://BUCKET_IP/index.html;
}
}
The bucket is an external IP from a separate project, cloud functions are internal to the project.
I don't seem to be able to find a way to handle NGINX style rules with a load balancer. How would I handle these sorts of complex (regex-style) reverse proxies using built in GCP products?

How do I set an error page to an external location without a redirect?

I am trying to use nginx to set up a SPA at an external location. I want
all the /api requests to go to the api server
all other requests to go to the static server (node:8081)
otherwise, all requests should show the content of the root of the static server.
This is my nginx.conf
events { }
http {
server {
location / {
proxy_pass http://node:8081/;
proxy_intercept_errors on;
error_page 404 #fallback;
}
location /api/ {
proxy_pass http://play:9000/api/;
}
location #fallback {
proxy_pass http://node:8081;
}
}
}
However, with this configuration nginx serves a 301 result and redirects the browser to the root of the static server, but the SPA needs the URL in order to show the proper (SPA) view.
How do I configure the error_page to display the content of http://node:8081 without redirecting there?

Nginx reverse proxy to multiple sites on different locations

Is it possible to configure nginx reverse proxy where http://localhost/a/ leads to 1 site and http://localhost/b/ to another? I tried this config:
server {
listen 80;
server_name localhost;
location /a/ {
proxy_pass http://apache.org/;
}
location /b/ {
proxy_pass http://www.gnu.org/;
}
it almost works, but all the links returned by web pages are missing /a/ or /b/ prefix so it can't load any pictures, styles and etc. For example link http://localhost/css/styles.css is not working, but http://localhost/a/css/styles.css is working.
Is there a directive that will append all links on page with suitable prefix? Or there is different approach to put a websites on separate locations?
#ivan-shatsky, Thank you very much.
Just wanted to add working config if some1 else needs.
map $http_referer $prefix {
~https?://[^/]+/a/ a;
default b;
}
server {
listen 80;
server_name localhost;
location / {
try_files /dev/null #$prefix;
}
location /a/ {
proxy_pass http://apache.org/;
}
location #a {
proxy_pass http://apache.org;
}
location /b/ {
proxy_pass http://www.gnu.org/;
}
location #b {
proxy_pass http://www.gnu.org;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}```

Nginx reverse proxy to frontend and backend

I have two react app running on localhost:3000(frontend) and localhost:3001(backend). I want to serve both backend and front end from same server_name.. For example, if a user hits example.com the Nginx should route the traffic to frontend running on (localhost:3000) and if a user hits example.com/admin/login traffic should get routed to the backend (localhost:3001).
'''
server {
listen 80;
server_name example.com;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
location / {
proxy_pass http://localhost:3001;
}
location /admin-login {
proxy_pass http://localhost:3000;
}
}
'''
Using above configuration. I have frontend running on example.com. However, when I call example.com/admin/login I am getting redirected to app running on frontend (localhost:3000) instead of backend running on (localhost:3001).
Updating as per the answer given below. I have below configuration. it still have the same behavior.
server {
listen 80;
server_name example.com;
location /admin-login {
proxy_pass http://127.0.0.1:3000/admin-login;
}
location / {
proxy_pass http://127.0.0.1:3001;
}
location /home {
proxy_pass http://127.0.0.1:3001/home;
}
location /login {
proxy_pass http://127.0.0.1:3001/login;
}
location /signup {
proxy_pass http://127.0.0.1:3001/signup;
}
location /article {
proxy_pass http://127.0.0.1:3001/article;
}
}
I think the problem here is that
location / {
proxy_pass http://localhost:300
}
matches all queries so will also redirect anything to /admin-login
You could either rearrange your blocks to have the admin-login block above the / block in the config file, or make the adjustment below:
location = / {
proxy_pass http://localhost:300
}
This adjusted block should only redirect queries to / rather than /*
If you want to read more, it's explained in the documentation here - https://nginx.org/en/docs/http/ngx_http_core_module.html#location

How to simulate upstream with Nginx for dynamic subdomains

I would proxy a request like the upstream solution.
server_name ~^(?<subdomain>.+)\.example\.com$;
root /dev/null;
location / {
error_page 502 #nextserver;
resolver 127.0.0.1:53 valid=300s;
proxy_pass "https://$subdomain";
}
location #nextserver {
error_page 502 #error;
resolver 127.0.0.1:53 valid=300s;
proxy_pass "https://$subdomain-blahblah";
}
location #error {
return 502 'Service is not available';
}
As you can see I would check https://$subdomain and if it doesn't exist or it down then checks https://$subdomain-blahblah.
it works fine but the problem happen when the second server is down, then Nginx doesn't provide Service is not available message.
So the scenario is like
check Server A -> down
check Server B -> down
Return custom error
I couldn't use upstream because the name of servers is dynamic.
I would suggest you to solve this problem differently. Check out this sample. It shows how you can approach the problem:
http{
listen 80;
root /path/to/static/files;
upstream_server subdomain1{
server 192.168.1.100:8000;
server 192.168.1.101:8000;
}
upstream_server subdomain2{
server 192.168.1.102:8000;
server 192.168.1.103:8000;
}
location / {
server_name subdomain1.example.com;
proxy_pass http://subdomain1;
include /etc/nginx/proxy_pass;
}
location / {
server_name subdomain2.example.com;
proxy_pass http://subdomain2;
include /etc/nginx/proxy_pass;
}
}

Resources