NGINX: serve static file when proxy_pass fails - nginx

I have a frontend running nginx which proxy requests to a backend running a web service.
I would like to serve a static file if the backend service is down.
Here is the configuration file I am using:
location ~ /api/admin {
rewrite /xxxx/(.+) /$1 break;
error_page 404 502 =200 /themes/yyyy/themes.json;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
add_header Access-Control-Allow-Credentials true;
add_header Access-Control-Allow-Origin '*';
add_header Access-Control-Allow-Methods 'GET, POST';
proxy_intercept_errors on;
proxy_pass http://xxxx;
}
location = /themes/yyyy/themes.json {
rewrite /themes/yyyy/themes.json /api/admin/thematics/edito;
}
when I call :
http://url/themes/geoportail/themes.json
I receive a 502 error from nginx, instead of 200 and the static file...
2014/08/25 17:02:35 [error] 13551#0: *6719 connect() failed (111: Connection refused) while connecting to upstream, client: 160.92.103.160, server: uri, request: "GET /themes/yyyy/themes.json HTTP/1.1", upstream: "http://IP:PORT/api/admin/thematics/edito", host: "", referrer: ""

I'm posting a solution I've found, feel free to propose something more elegant.
location ~ /api/admin {
rewrite /xxxx/(.+) /$1 break;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
add_header Access-Control-Allow-Credentials true;
add_header Access-Control-Allow-Origin '*';
add_header Access-Control-Allow-Methods 'GET, POST';
proxy_intercept_errors on;
proxy_pass http://xxxx;
error_page 404 502 503 504 =200 #statictheme;
}
location #statictheme {
try_files $uri /themes/yyyy/themes.json last;
}
location = /themes/yyyy/themes.json {
rewrite /themes/yyyy/themes.json /api/admin/thematics/edito;
}

Related

Correct proxy configuration for nginx server to access rest api

I have a nginx-server configured as follows:
server {
listen 3000;
listen [::]:3000;
server_name .+;
add_header Strict-Transport-Security "max-age=15552000; includeSubDomains" always;
...
index index.html;
root /usr/share/nginx/html;
location /cam/ {
proxy_pass http://cam:8000/;
}
location /api {
proxy_pass https://some_ip:some_port;
proxy_pass_request_headers on;
proxy_set_header X-API-KEY xxxxx;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $server_name;
proxy_ssl_server_name on;
}
location /share/ {
alias /usr/src/share;
}
location / {
try_files $uri $uri/ /index.html;
}
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range' always;
client_max_body_size 1M;
keepalive_timeout 10;
}
For displaying my frontend, this configuration works fine. The proxy for the cam is also working correctly.
I am getting problems in the configuration of the proxy for the api. The api has a sanity-check under "https://some_ip:some_port", which just returns "200: ok". Otherwise I should be able to make request using a fetch request such as
const res = await fetch(`api/subaddress/${system_id.toString()}/base`, {
method: 'POST',
headers: {
'Content-type': 'application/json',
'X-API-KEY': xxxxx,
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'HEAD, GET, POST, PUT, PATCH, DELETE',
'Access-Control-Allow-Headers': 'Origin, Content-Type, X-Auth-Token'
},
body: JSON.stringify(data_body),
});
Which, if successfull, returns "202: ok".
If I make such a request using curl, it works just fine (both of the requests), so the api should not be the problem.
At the current configuration, I get a "200: ok", which tells me that I have connected to the api, but the proxy does not take in account my subaddresses.
Besides the given configuration, I tried the following:
location /api {
proxy_pass https://some_ip:some_port$request_uri;
...
}
which always gives me "502: bad gateway"
location /api/ {
proxy_pass https://some_ip:some_port/;
...
}
which always gives me "403: forbidden"
location /api {
rewrite ^/api/(.*) /$1 break;
proxy_pass https://some_ip:some_port/$1;
...
}
which causes nginx to crash, as it tells me that it cannot resolve it. I would like to avoid using a resolver, unless definitly necessary (I have tried it using a resolver before too and it did not work either).
What is the correct way to accomplish this?
I solved this. Apparently the 403: forbidden was caused my some of the configurations of the proxy. After removing those, I did not get that error anymore.
In the end I used
location /api {
rewrite ^/api/(.*) /$1 break;
proxy_pass https://some_ip:some_port/$1;
...
}
which I made work by putting
resolver 1.1.1.1 valid=30s;
at the top of the configuration file.

Nginx Config for Camunda Webapp

I am configuring camunda webapp with nginx reverse proxy. Applications is loading perfectly fine using location / (Root Path). But I need to access it using a readable location path e.g. /process/. I tried a lot with several rewrites and redirections but to no success.
At root path all the static content loads but with other location path it fails. I'm a newbie in Nginx So it would make complete sense if i'm missing something very trivial.
Here is my config with location as Root Path:
server {
listen 8080;
server_name abc.xyz.net;
rewrite_log on;
error_log /var/log/nginx/localhost.error_log notice;
location / {
# Simple requests
if ($request_method ~* "(GET|POST)") {
add_header "Access-Control-Allow-Origin" *;
}
# Preflighted requests
if ($request_method = OPTIONS ) {
add_header "Access-Control-Allow-Origin" *;
add_header "Access-Control-Allow-Methods" "GET, POST, OPTIONS, HEAD";
add_header "Access-Control-Allow-Headers" "Authorization, Origin, X-Requested-With, Content-Type, Accept";
return 200;
}
proxy_pass http://camunda-webapp.xyz.net;
proxy_set_header X-Forwarded-Host $host/;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass_request_headers on;
proxy_read_timeout 180s;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
On another context, If I try to give full URL in proxy_pass(Refer below config) then it works but the browser URL gets completely changed to proxy_pass URL.(I had even tried with proxy_redirect to retain the original URL but it doesn't work)
server {
listen 8080;
server_name abc.xyz.net;
rewrite_log on;
error_log /var/log/nginx/localhost.error_log notice;
location /process/ {
rewrite ^\/(?>[process]+)(\/.*) $1 break;
# Simple requests
if ($request_method ~* "(GET|POST)") {
add_header "Access-Control-Allow-Origin" *;
}
# Preflighted requests
if ($request_method = OPTIONS ) {
add_header "Access-Control-Allow-Origin" *;
add_header "Access-Control-Allow-Methods" "GET, POST, OPTIONS, HEAD";
add_header "Access-Control-Allow-Headers" "Authorization, Origin, X-Requested-With, Content-Type, Accept";
return 200;
}
proxy_pass http://camunda-webapp.xyz.net/app/welcome/default;
proxy_redirect http://camunda-webapp.xyz.net/app/welcome/default https://abc.xyz.net/process
proxy_set_header X-Forwarded-Host $host/process;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass_request_headers on;
proxy_read_timeout 180s;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
Any kind of info or help will be appreciated. Thanks in Advance.
Bella Ciao!
I think the trick is to specify the same location context of the nginx as the context path of the your application.
Also, please remove url rewrite as its not needed here.

nginx proxy is not working using subdomain

i have two domains
alpha.mydomain.com and api-alpha.mydomain.com
I am trying to use nginx as a proxy
i am getting the error
Access to XMLHttpRequest at 'https://api-alpha.mydomain.com/dup-check'
from origin 'https://alpha.mydomain.com' has been blocked by CORS
policy: Response to preflight request doesn't pass access control
check: No 'Access-Control-Allow-Origin' header is present on the
requested resource.
i would think based on my setup , the request should not be using api-alpha.mydomain.com but 127.0.0.1 (and not getting the CORS error)
NOTE:: i am using cloudflare https so the console errors are https by cloudflare is the SSL and talking to port 80 to my nginx server
this is part of my nginx config
server {
listen 80;
server_name alpha.mydomain.com ;
access_log /var/log/nginx.access_log main;
root /home/mydomain/react-front/dist;
location / {
try_files $uri $uri/ /index.html;
}
}
server {
listen 80;
server_name api-alpha.mydomain.com ;
access_log /var/log/nginx-api-alpha-access.log main;
location /{
proxy_pass http://127.0.0.1:4001/;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-NginX-Proxy true;
proxy_ssl_session_reuse off;
proxy_set_header Host $http_host;
proxy_redirect off;
}
}
This is the entry from the nginx-api-alpha-access.log
"OPTIONS /dup-check HTTP/1.1" 502 750 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36" "-"
This is the entry from /var/log/nginx/error.log
[error] 1280#1280: *12 connect() failed (111: Connection refused) while connecting to upstream, client: 172.xx.xxx.xxx, server: api-mydomain.trigfig.com, request: "OPTIONS /dup-check HTTP/1.1", upstream: "http://127.0.0.1:4001/dup-check", host: "api-alpha.mydomain.com"
Thanks, not sure what i am missing in my config
try change to
server {
listen 80;
server_name alpha.mydomain.com ;
access_log /var/log/nginx.access_log main;
root /home/mydomain/react-front/dist;
location / {
try_files $uri $uri/ /index.html;
}
}
server {
listen 80;
server_name api-alpha.mydomain.com ;
access_log /var/log/nginx-api-alpha-access.log main;
location /{
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization';
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain; charset=utf-8';
add_header 'Content-Length' 0;
return 204;
}
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization';
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range,Authorization';
proxy_pass http://127.0.0.1:4001/;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-NginX-Proxy true;
proxy_ssl_session_reuse off;
proxy_set_header Host $http_host;
proxy_redirect off;
}
}

nginx vhost error : static files not found

I have a vhost who has problem serving static files :
http://graphite.domain.fr/static/img/carbon-fiber.png 404
graphite.conf
server {
listen 80;
server_name graphite.domain.fr;
client_max_body_size 64M;
keepalive_timeout 5;
# path for static files
root /opt/graphite/webapp/content;
location /media/ {
root /opt/graphite/lib/python2.7/site-packages/django/contrib/admin;
}
auth_basic "Area 51, password please!";
auth_basic_user_file /home/ansible/grafana/.htpasswd;
location / {
if ($http_origin ~* (http://graphite.domain.fr)) {
set $cors "true";
}
if ($cors = 'true') {
add_header Access-Control-Allow-Origin $http_origin;
add_header "Access-Control-Allow-Credentials" "true";
add_header "Access-Control-Allow-Methods" "GET, OPTIONS";
add_header "Access-Control-Allow-Headers" "Authorization, origin, accept";
}
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Scheme $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_connect_timeout 10;
proxy_read_timeout 10;
proxy_pass http://localhost:8080/;
}
}
The images are in the right folder, with correct chmod (644) readable by www-data :
What might be the cause ? All resources under /static/ url gives me 404 error

Elasticsearch : Connection refused while connecting to upstream

I've set up an Elasticsearch server with Kibana to gather some logs.
Elasticsearch is behind a reverse proxy by Nginx, here is the conf :
server {
listen 8080;
server_name myserver.com;
error_log /var/log/nginx/elasticsearch.proxy.error.log;
access_log off;
location / {
# Deny Nodes Shutdown API
if ($request_filename ~ "_shutdown") {
return 403;
break;
}
# Pass requests to ElasticSearch
proxy_pass http://localhost:9200;
proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
# For CORS Ajax
proxy_pass_header Access-Control-Allow-Origin;
proxy_pass_header Access-Control-Allow-Methods;
proxy_hide_header Access-Control-Allow-Headers;
add_header Access-Control-Allow-Headers 'X-Requested-With, Content-Type';
add_header Access-Control-Allow-Credentials true;
}
}
Everything works well, I can curl -XGET "myserver.com:8080" to check, and my logs come in.
But every minute or so, in the nginx error logs, I get that :
2014/05/28 12:55:45 [error] 27007#0: *396 connect() failed (111: Connection refused) while connecting to upstream, client: [REDACTED_IP], server: myserver.com, request: "POST /_bulk?replication=sync HTTP/1.1", upstream: "http://[::1]:9200/_bulk?replication=sync", host: "myserver.com"
I can't figure out what it is, is there any problem in the conf that would prevent some _bulk requests to come through ?
Seems like upstream and a different keepalive is necessary for the ES backend to work properly, I finally had it working using the following configuration :
upstream elasticsearch {
server 127.0.0.1:9200;
keepalive 64;
}
server {
listen 8080;
server_name myserver.com;
error_log /var/log/nginx/elasticsearch.proxy.error.log;
access_log off;
location / {
# Deny Nodes Shutdown API
if ($request_filename ~ "_shutdown") {
return 403;
break;
}
# Pass requests to ElasticSearch
proxy_pass http://elasticsearch;
proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
# For CORS Ajax
proxy_pass_header Access-Control-Allow-Origin;
proxy_pass_header Access-Control-Allow-Methods;
proxy_hide_header Access-Control-Allow-Headers;
add_header Access-Control-Allow-Headers 'X-Requested-With, Content-Type';
add_header Access-Control-Allow-Credentials true;
}
}

Resources