Nginx proxy_pass - not able to reverse proxy with location other than / - nginx

I have following in my nginx.conf file in windows 10.
#user nobody;
worker_processes 1;
error_log "C:\\nginx\\nginx-1.23.1\\logs\\error.log";
events {
worker_connections 1024;
}
http {
default_type application/octet-stream;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
gzip on;
include "C:\\nginx\\nginx-1.23.1\\conf\\mime.types";
server {
listen 8009;
server_name server;
default_type application/octet-stream;
location / {
root html;
index index.html index.htm;
}
location /myapp/ {
proxy_pass http://172.17.122.45:8100/;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $server_name;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Real-IP $remote_addr;
#sub_filter_types *;
sub_filter 'action="/' 'action="/myapp/';
sub_filter 'href="/' 'href="/myapp/';
sub_filter 'src="/' 'src="/myapp/';
sub_filter_once off;
}
}
}
I am trying to access app on http://server:8009/myapp/, but not able to access. Able to proxy_pass my app on location /, but not able to do it on any other location.
It's able to load the js files but not few json files and images. Showing console error in browser as below.
main.5e06c118abe3f1a0.js:1 ERROR Error: Uncaught (in promise): zx: {"headers":{"normalizedNames":{},"lazyUpdate":null},"status":200,"statusText":"OK","url":"http://server:8009/assets/envsettings.json","ok":false,"name":"HttpErrorResponse","message":"Http failure during parsing for http://server:8009/assets/envsettings.json","error":{"error":{},"text":"<!doctype html><html lang=\"en\"><head><meta charset=\"utf-8\"/><base href=\"/\"/><meta content=\"width=device-width,initial-scale=1\" name=\"viewport\"/><meta content=\"#081C42\" media=\"(prefers-color-scheme: light)\" name=\"theme-color\"/><meta content=\"#081C42\" media=\"(prefers-color-scheme: dark)\" name=\"theme-color\"/><meta content=\"MinIO Console\" name=\"description\"/><link href=\"./styles/root-styles.css\" rel=\"stylesheet\"/><link href=\"./apple-icon-180x180.png\" rel=\"apple-touch-icon\" sizes=\"180x180\"/><link href=\"./favicon-32x32.png\" rel=\"icon\" sizes=\"32x32\" type=\"image/png\"/><link href=\"./favicon-96x96.png\" rel=\"icon\" sizes=\"96x96\" type=\"image/png\"/><link href=\"./favicon-16x16.png\" rel=\"icon\" sizes=\"16x16\" type=\"image/png\"/><link href=\"./manifest.json\" rel=\"manifest\"/><link color=\"#3a4e54\" href=\"./safari-pinned-tab.svg\" rel=\"mask-icon\"/><title>MinIO Console</title><script defer=\"defer\" src=\"./static/js/main.44b939e3.js\"></script><link href=\"./static/css/main.90d417ae.css\" rel=\"stylesheet\"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id=\"root\"><div id=\"preload\"><img src=\"./images/background.svg\"/> <img src=\"./images/background-wave-orig2.svg\"/></div><div id=\"loader-block\"><img src=\"./Loader.svg\"/></div></div></body></html>"}}
It's trying to access http://server:8009/assets/envsettings.json instead of http://server:8009/myapp/assets/envsettings.json. What I'm doing wrong here? I'm pretty new to nginx.

Related

(Nginx Windows) nginx: [emerg] unknown directive "serversupstream"

I got this code while executing nginx:
nginx: [emerg] unknown directive "serversupstream" in C:\nginx-1.17.9/conf/nginx.conf:15
This is my nginx.conf:
#user nobody;
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
# List of application
serversupstream portal_server {
server 127.0.0.1:9510;
}
upstream portal_web_server {
server 127.0.0.1:8085;
}
server {
listen 8001;
server_name localhost;
location /api {
proxy_pass <http://portal_server;>
proxy_http_version 1.1;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /dte {
proxy_pass <http://portal_web_server;>
proxy_http_version 1.1;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /simulacion {
proxy_pass <http://portal_web_server;>
proxy_http_version 1.1;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
include servers/*;
}
I don't know that error message, what it is?
EDIT:
According to http://nginx.org/en/docs/dirindex.htm there is no serversupstream I don't understand, I'm just using a nginx.conf that many other guys in the team are using, but they are on mac and/or linux, I'm the only one in Windows.
So, I change serversupstream to upstream and there it triggers another error, it's complaining about the prefix for:
proxy_pass <http://portal_web_server;>
So I change removed those <> and there I tried again, now nginx doesn't show anything in the console... just this:
change encoding of the configfile to Utf8.
Don't use built'in Notepad.exe to Save as to Uft8, it will save as Utf8 BOM.
Use Notepad++ or other editor.

How to host flask-restx swagger UI using nginx reverse proxy

I have tried multiple way to fix the reverse proxy, but not getting any luck.
I followed the below url to fix the issue: https://github.com/noirbizarre/flask-restplus/issues/223
The nginx config is as follows:
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name localhost;
location / {
root html;
index index.html index.htm;
}
location /api {
proxy_pass http://localhost:5000; #change to your port
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
Add a rewrite clause to the api
rewrite ^/api/(.*) /$1 break;

Why do I get 404 on nginx reverse proxy?

Below is my config and I'm getting 404 on all routes defined apart from the well-known route and I don't understand why.
If I make a request to http://example.tech/connect I get a 404 and if I make a request to http://api.example.tech I also get a 404.
I can't see where I've gone wrong as this looks like it should work!
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
error_log /var/log/nginx/error.log warn;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
#REMOVE REFERENCE TO FILES THAT HAVE "server" and "location" blocks in them so we can do it all in this file
#include /etc/nginx/conf.d/*.conf;
# issue with ip and the nginx proxy
real_ip_header X-Forwarded-For;
set_real_ip_from 0.0.0.0/0;
server {
listen 80;
listen [::]:80;
server_name example.tech;
location /.well-known/openid-configuration {
proxy_pass https://myapp.net;
proxy_redirect off;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection keep-alive;
#proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_set_header X-Forwarded-Host $host;
#proxy_set_header X-Forwarded-Proto $scheme;
client_max_body_size 10m;
client_body_buffer_size 128k;
proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_buffers 32 4k;
}
location /connect {
proxy_pass https://myapp.net;
proxy_redirect off;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection keep-alive;
#proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_set_header X-Forwarded-Host $host;
#proxy_set_header X-Forwarded-Proto $scheme;
client_max_body_size 10m;
client_body_buffer_size 128k;
proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_buffers 32 4k;
}
location /auth {
proxy_pass https://myapp.net;
proxy_redirect off;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection keep-alive;
#proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_set_header X-Forwarded-Host $host;
#proxy_set_header X-Forwarded-Proto $scheme;
client_max_body_size 10m;
client_body_buffer_size 128k;
proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_buffers 32 4k;
}
}
server {
listen 80;
listen [::]:80;
server_name api.example.tech;
location /auth/ {
proxy_pass https://myapp.net;
proxy_redirect off;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection keep-alive;
#proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_set_header X-Forwarded-Host $host;
#proxy_set_header X-Forwarded-Proto $scheme;
client_max_body_size 10m;
client_body_buffer_size 128k;
proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_buffers 32 4k;
}
}
}
Needed a forward slash on the end of the proxy_pass for some reason
You need a specific uri in proxy_pass directive, not a backslash. But in your case here, a backslash is acting as the specific uri. Nginx replaces '/auth'(for example) with '/'(you've added).
In fact, the answer you put is right, turning proxy_pass http://myapp.net; to proxy_pass http://myapp.net/;.
The reason is that proxy_pass would work in two different ways with/without a specific uri. More details about this directive on nginx.org. Blow is some content quoted in that link.
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:
location /name/ {
proxy_pass http://127.0.0.1/remote/;
}
If proxy_pass is specified without a URI, the request URI is passed to the server in the same form as sent by a client when the original
request is processed, or the full normalized request URI is passed
when processing the changed URI:
location /some/path/ {
proxy_pass http://127.0.0.1;
}
In your case, without URI in proxy_pass directive, so /auth would be passed to backend server. Unfortunately, your backend server does not have the /auth resource, so 404 is returned. If your backend server does have /auth to be processed, you would never get 404 error while requesting uri /auth.
Here are two examples, which hopefully clarify things.
location /some-path {
proxy_pass http://server:3000;
}
In this case the proxied server (target) must handle the route /some-path. If handling something else, like / only, it will return an error to Nginx.
One solution is to add a trailing / e.g.:
location /some-path {
proxy_pass http://server:3000/;
}
Now requests sent to /some-path can (and must) be handled by the route / on the proxied server side. However, this may cause issues with some servers. For example, with Express, curl localhost/some-path would be handled fine by Express, whereas curl localhost/some-path/ would cause Express to return Cannot GET //.
This might be different for your target server, but the principle is the same: if you specify the server only, the full path in location is passed to the server, so it must be handled accordingly.
This is my case how I've get 404 instead of 502:
# let's define some proxy pass
location ~ /.well-known/acme-challenge {
proxy_pass http://127.0.0.1:5080; # this backend doesn't exist which leads to 502
proxy_set_header Host $host;
}
# this is a default directives
error_page 500 502 503 504 /50x.html; # this is a reason to redirect 502 to 50x.html
location = /50x.html { # but this file doesn't exist in root so we get 404 instead of 502
root /usr/share/nginx/html;
}

Nginx proxy_pass fail on heroku

EDIT:
Just figure it out! My configuration is ok. It because my cancellation of CNAME is not valid yet. After a while it automatically map by Nginx.
========================================================================
I try to url masking with Nginx on heroku. It works great until I use a CNAME on my entry domain.
When I directly keyup https://foobar.herokuapp.com/search-beta, request will be forward to FORWARD_HOST as expect with the url correct. But when I try to access my app with a CNAME (let's say we have a CNAME https://www.foobar.com to https://foobar.herokuapp.com) like https://www.foobar.com/search-beta, the request will be redirect to my FORWARD_HOST.
Is there anything I miss? Can any one give me some tips?
thanks
My Nginx config
daemon off;
#Heroku dynos have at least 4 cores.
worker_processes <%= ENV['NGINX_WORKERS'] || 4 %>;
events {
use epoll;
accept_mutex on;
worker_connections 1024;
}
http {
gzip on;
gzip_comp_level 2;
gzip_min_length 512;
server_tokens off;
log_format l2met 'measure#nginx.service=$request_time request_id=$http_x_request_id';
access_log logs/nginx/access.log l2met;
error_log logs/nginx/error.log;
include mime.types;
default_type application/octet-stream;
sendfile on;
#Must read the body in 5 seconds.
client_body_timeout 5;
upstream app_server {
server unix:/tmp/nginx.socket fail_timeout=0;
}
server {
listen <%= ENV["PORT"] %>;
server_name _;
keepalive_timeout 5;
location / {
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;
proxy_redirect off;
proxy_pass http://app_server;
}
location /assets {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
set $proxy_pass http://app_server;
if ($http_referer ~ "search-beta") {
set $proxy_pass <%= ENV["FORWARD_HOST"] %>;
}
proxy_pass $proxy_pass;
}
location /search-beta {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For
$proxy_add_x_forwarded_for;
proxy_pass <%= ENV["FORWARD_HOST"] %>;
}
}
}

serving static directory folder in nginx

I have below folder structure in my app
/app/server - has content for api
/app/static - has images, js and css files in respective folder like (/static/images,/static/js... etc)
upstream pythonapp {
server 127.0.0.1:8080;
}
server {
listen 80;
server_name www.example.com;
error_log /home/LogFiles/docker/error.log warn;
root /app;
index index.html index.htm;
location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
expires 1d;
}
location /static {
autoindex on;
alias /app/static/;
}
location / {
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
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_http_version 1.1;
proxy_pass http://pythonapp;
proxy_cache_bypass $http_upgrade;
}
}
Everything worked as expected but today I realized that we were using
http://xyz.abc/images/abc.gif instead of
http://xyz.abc/static/images/abc.gif
As there is no static in URL, my /static rule won't be honored anymore.
I have read articles online on different approaches but none of them had anything close to URL without /static in it. Anyone had this issue before and aware of a solution ?
NEW EDITS :
I have changed content to below as #shdaws mentioned. I had to change root in server level too to make it work.
server {
listen 80;
server_name www.example.com;
error_log /home/LogFiles/docker/error.log warn;
root /app/static;
index index.html index.htm;
location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
expires 1d;
}
location ^~ /(audio|build|images|style) {
autoindex on;
root /app/static;
}
location / {
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
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_http_version 1.1;
proxy_pass http://pythonapp;
proxy_cache_bypass $http_upgrade;
}
}
Now it serves static content in /app/static/images folder for http://abc.xyz/images/test.jpg url. But http://abc.xyz/images/d1/test.jpg doesn't work.
Edit :
- Above configuration works, it does serve sub-folder content too. Looks like I have some config issues with .mp3 files.
Change your static location to be images assuming abc.gif is located at /app/static/abc.gif:
# Serve /images/file.ext from /app/static/file.ext
location ^~ /images {
autoindex on;
alias /app/static;
}
If you're trying to serve the file from /app/static/images/abc.gif use root instead of alias, this will append the URL to the root:
# Serve /images/file.ext from /app/static/images/file.ext
location ^~ /images {
autoindex on;
root /app/static;
}
You can also use regex in the location for all directories you want:
location ^~ /(images|js|css) {
Thanks #sjdaws for helping with this issue. Below config works perfectly for my scenario.
worker_processes auto;
pid /var/run/nginx.pid;
daemon off;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /home/LogFiles/docker/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
gzip on;
upstream pythonapp {
server 127.0.0.1:8080;
}
server {
listen 80;
server_name www.example.com;
error_log /home/LogFiles/docker/error.log warn;
root /app/static;
index index.html index.htm;
location ~* \.(js|css|png|jpg|jpeg|gif|ico|mp3|html)$ {
expires 1d;
}
location / {
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
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_http_version 1.1;
proxy_pass http://pythonapp;
proxy_cache_bypass $http_upgrade;
}
}
}

Resources