StreamLit behind Nginx behind reverse proxy (load balancer) - nginx

I have a Docker app running on an Nginx webserver, that works fine connecting directly to the webserver. However, the webserver is behind a separate Nginx reverse proxy server (functioning as WAF, load balancer, and in some cases directs path specific requests to different servers - as in this specific case).
The internal server config, which works if I connect directly to this server, look like:
# redirect without the trailing slash because the author did not include the full path in the Docker app
location /apppath/editor {
return 302 /apppath/editor/;
}
location /apppath/editor/ {
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;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_pass http://0.0.0.0:8501/editor/;
}
location /apppath {
alias /var/www/dockerapp;
try_files $uri $uri/ =404;
}
I could not find examples of multiple levels of reverse proxy for a websocket app, so I have tried countless variations, but the public (LB/WAF) config currently looks like:
location /apppath {
#proxy_set_header X-Real-IP $remote_addr;
#proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
#proxy_headers_hash_bucket_size 128;
#proxy_set_header X-Forwarded-Proto $scheme;
proxy_redirect off;
proxy_set_header Host $host;
proxy_http_version 1.1;
#proxy_buffering off;
#proxy_set_header Forwarded "for=$proxy_add_x_forwarded_for;proto=$scheme";
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
#proxy_set_header Referer $http_referer;
proxy_pass https://10.0.6.13:443;
}
From the public location, requests to /apppath/pages.html work fine, but when I attempt to hit /apppath/editor/ I see only "Please wait..." with the "Made with Streamlit" tag at the bottom.
My browser shows repeated requests for /apppath/editor/healthz and the console is full of:
WebsocketConnection WebSocket onerror
Uncaught Error: Unsupported state transition
State: PINGING_SERVER
Event: CONNECTION_TIMED_OUT
...

Related

Use nginx location blocks with Shinyproxy

I recently successfully deployed a ShinyProxy + app using SSL with nginx and certbot in the following manner:
Dockerize ShinyProxy + app and launch on port 127.0.0.1:5001.
Create Nginx config and proxy_pass to 127.0.0.1:5001.
Secure using certbot.
This is the successful nginx.conf location section:
location / {
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;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_http_version 1.1;
proxy_redirect off;
proxy_read_timeout 90s;
proxy_pass http://127.0.0.1:5001;
}
This nicely redirects me to https://app.myweb.com/login as I have set up a CNAME. Important to note, {ShinyProxy} redirects to the login at the end automatically. On successful login the url redirects to https://app.myweb.com/app/website.
What I really struggle with is the following: adding a location block or as I understand it, include my upstream block into my downstream (correct my terms if I am wrong). So, have my url go from https://app.myweb.com/login to https://app.myweb.com/dashboard/login using the following configuration in nginx:
location /dashboard/ { # THIS IS WHAT I WANT TO ADD
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;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_http_version 1.1;
proxy_redirect off;
proxy_read_timeout 90s;
proxy_pass http://127.0.0.1:5001;
}
All that happens is, if I type https://app.myweb.com/dashboard/ it doesn't go to https://app.myweb.com/dashboard/login as I would expect, but redirects back to https://app.myweb.com/login which 404's.
Any advice on what I am doing wrong?

Nginx Reverse Proxy & Rewrite with Parameters

I'm trying to deploy a Bokeh Server application that requires an input parameter ("Part") in the form:
(1) http://127.0.0.1:5100/myapp?Part=1234-567
I want to use rewrite so that when a user hits the below URL
(2) http://<my_hostname>/myappRenamed/Part=1234-567
Nginx reverse proxies to URL (1)
Right now, my config file is similar to below.
location /myappRenamed/ {
proxy_pass http://127.0.0.1:5100;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_http_version 1.1;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host:$server_port;
proxy_buffering off;
}
This works when I hit
http://<my_hostname>/myappRenamed/myapp?Part=1234-567
Except I want the URL to be
http://<my_hostname>/myappRenamed/Part=1234-567
You should rewrite the URL first, making it URL friendly using nginx rewrite capabilities and the proxy it:
location /myappRenamed/ {
rewrite ^/myapp(.*) /$1 break;
proxy_pass http://127.0.0.1:5100;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_http_version 1.1;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host:$server_port;
proxy_buffering off;
}
I do not have your ENV so I can't really test the rule but you got the concept.

nginx and docker: route all requests from each service properly

I have several services running in docker (using docker-compose), each in its own container.
I am using nginx as the proxy server.
partial nginx.conf:
upstream a_servers {
server a:8080;
}
upstream b_servers {
server b:8080;
}
server {
location / {
proxy_pass http://a_servers/;
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-Host $server_name;
}
location /b {
proxy_pass http://b_servers;
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-Host $server_name;
}
}
Problem:
These two services both need to load their own /js/build.js file. However, when service b makes a request for /js/build.js, nginx routes it to the first option and makes a request for the build.js from service a instead.
Is there a way to prepend /b to all requests coming from service b? Also, what is the name for what I'm trying to do?

nginx proxy doesn't wait for slow meteor app

I have a meteor app running at meteor:3000, but some files are served to the client very slow (up to 10s), because the server isn't powerful.
It works when accessing the meteor app directly, but using the nginx reverse proxy the files that need long to serve don't get served at all, they result in a 404.
This is my proxy configuration
location / {
proxy_pass http://meteor:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forward-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forward-Proto http;
proxy_set_header X-Nginx-Proxy true;
proxy_redirect off;
proxy_connect_timeout 100000000s; # these values seem to not affect nginx at all
proxy_send_timeout 150000000s;
proxy_read_timeout 200000000s;
}
Loading the site using reverse proxy
Loading the site directly

jupyterhub nginx reverse proxy

I'm trying to get a reverse proxy (nginx) to work with juypterhub. I want the service available at myurl.com/jhub/. I placed the following in the config:
location /jhub/ {
proxy_pass http://127.0.0.1:8000/;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-NginX-Proxy true;
#WebSocket support
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 86400;
}
However, when I try the url after restarting the proxy jupyterhub is not available and I get a '404' Not Found error. I've tried every combination of ports and address with no luck. The same approach works just fine for RStudio server.... What am I missing?

Resources