Dashboard 2.0 behind reverse proxy (nginx)
Hi,
I am trying to set up a reverse proxy with Nginx for the new Node-RED Dashboard 2.0. Previously, with Dashboard 1.0, I was able to access the dashboard easily by configuring Nginx to route requests based on the device's IP address or FQDN.
I would like to achieve the same setup for Dashboard 2.0, but I am facing issues with WebSocket connections. It seems that my Nginx configuration is not handling WebSockets correctly, and the dashboard does not work as expected.
Could you provide guidance on the correct Nginx configuration to ensure WebSocket support for Dashboard 2.0?
Thanks!
@WoMec I don't use Nginx myself, but "perhaps" you can find something useful here
Hello @WoMec I have this (I have just migrated to 2.0 this week) in my nginx.conf file (using docker-compose) and I have it working (in future I want to leave location at '/'). (see at bottom)
But THIRD PARTY NODES are NOT working. I get this errores in browser console
https://domain.net/resources/@flowfuse/node-red-dashboard-2-ui-led/ui-led.umd.js net
ERR_ABORTED 404 (Not Found)
@bartbutenaers do uou know if this is a "problem" of all third party nodes or a general "problem" of Dashboard 2.0?
server {
listen 80;
listen [::]:80;
server_name domain.net;
server_tokens off; #Disable the Nginx version in headers for security
location /.well-known/acme-challenge/ {
allow all;
root /var/www/certbot;
}
location / {
return 301 https://$server_name$request_uri;
}
#Logs for Nginx access and errors
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
location ~ /\.ht { deny all; }
location = /favicon.ico { log_not_found off; access_log off; }
location = /robots.txt { log_not_found off; access_log off; allow all; }
}
server {
listen 443 ssl;
listen [::]:443 ssl;
http2 on; # Activa HTTP/2 de forma explícita
server_name domain.net;
server_tokens off; #Disable the Nginx version in headers for security
ssl_certificate /etc/letsencrypt/live/domain.net/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/domain.net/privkey.pem;
ssl_session_timeout 1d;
ssl_session_cache shared:MozSSL:10m; # about 40000 sessions
ssl_session_tickets off;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
# Node-RED
location /nr/ {
proxy_pass http://nodered:1880/;
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;
# WebSocket support
proxy_http_version 1.1;
proxy_cache_bypass $http_upgrade;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
#new nodered dashboard 2.0
location /dash/ {
proxy_pass http://nodered:1880/dashboard/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Referer "";
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_cache_bypass $http_upgrade;
}
#old nodered ui
location / {
proxy_pass http://nodered:1880/ui/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
# Grafana Dashboard
location /graf/ {
proxy_pass http://grafana:3000/;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
}
# Logs for Nginx access and errors
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
location ~ /\.ht { deny all; }
location = /favicon.ico { log_not_found off; access_log off; }
location = /robots.txt { log_not_found off; access_log off; allow all; }
}
This may be the same problem https://github.com/FlowFuse/node-red-dashboard/issues/1024
In my humble opinion, I think nowadays working with docker and nignx is a must. What do you think? Does it have a easy solution?
@ortegafernando how are you installing your third-party nodes? Via the palette manager? or as global installs?
@ortegafernando how are you installing your third-party nodes? Via the palette manager? or as global installs?
@joepavitt By pallete manager. If you need any log or something from me, please ask me
@ortegafernando if you have a look at #1615 I think I have found the problem. If you setup httpAdminRoot to 'nr' and then proxy /nr to http://nodered:1880/nr/ then I think that may provide a workaround. That is if I understand the nginx config correctly.
@WoMec is your problem solved with the help of @WoMec's sample configuration?
@ortegafernando if you have a look at #1615 I think I have found the problem. If you setup httpAdminRoot to 'nr' and then proxy /nr to http://nodered:1880/nr/ then I think that may provide a workaround. That is if I understand the nginx config correctly.
Hi @colinl, this is what I have now in docker-compose.yml file:
nodered:
image: nodered/node-red:4.0
container_name: nodered
environment: #complete path will be ROOT/NODE_ROOT or ROOT/ADMIN_ROOT. Admin is where I edit, and Node is where they are exposed
# - NODE_RED_HTTP_ADMIN_ROOT=/
# - NODE_RED_HTTP_NODE_ROOT=/api
- NODE_RED_HTTP_ROOT=/nr
volumes:
- ./nodered-data:/data
restart: unless-stopped
And this is what browser console says when I access to dashboard 2.0 (everything works fine but third party nodes):
setup object:
{
"RED": {
"httpAdminRoot": "/",
"httpNodeRoot": "/"
},
"socketio": {
"path": "/dash/socket.io"
},
"basePath": "/dash"
}
Some page's information:
{
"path": "/dash/router",
"name": "Page:Router"
}
And errors:
https://mydomain.com/resources/@cgjgh/node-red-dashboard-2-ui-scheduler/ui-scheduler.umd.js
https://mydomain.com/dashboard/favicon.ico
https://mydomain.com/dashboard/favicon.svg
I have not changed anthing in settings.js so I supposed that httpAdminRoot is to default one ''. I am not an expert, but nginx will convert all '\nr' urls to 'http://nodered:1880/' so "in front of the eyes of nodered" httpAdminRoot is '', nothing related with '\nr'
In nginx.conf I have:
# Node-RED
location /nr/ {
proxy_pass http://nodered:1880/;
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;
# WebSocket support
proxy_http_version 1.1;
proxy_cache_bypass $http_upgrade;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
#new nodered dashboard 2.0
location /dash/ {
proxy_pass http://nodered:1880/dashboard/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Referer "";
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_cache_bypass $http_upgrade;
}
#old nodered ui
location / {
proxy_pass http://nodered:1880/ui/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
I have changed these last line in nginx.conf to:
#old nodered ui -> NO. Change to make work dash2.0
location / {
proxy_pass http://nodered:1880/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
And now I can see third party nodes. But also I can acccess to admin (where we edit nodes) in both cases (of course I could delete the /nr/ entry in my nginx.conf file):
https://mydomain.com/
https://mydomain.com/nr
What I want finally want to have is this type of proxy:
admin (where I edit nodes): /nr
dashboard 2.0: /
old dashboard: /ui or forget it.
I make these changes:
# Node-RED
location /nr/ {
proxy_pass http://nodered:1880/;
...
}
#new nodered dashboard 2.0
location / {
proxy_pass http://nodered:1880/dashboard/;
....
}
#old nodered ui
location /ui/ {
proxy_pass http://nodered:1880/ui/;
....
}
/: I can not see anthing in mydomain.com, some errors about https://mydomain.com/sw.js /nr/: works perfectly /ui/: works perfectly
May be because dashboard 2.0 must be in a subpath of main nodered admin page?
I think that there are two problems:
- Dashboard 2.0 could be able to be in a different url path from nodered admin, not only in a subpath. I don't know if this is easy to solve by Flowfuse.
- Third party nodes need to work with relative path of the dashboard 2.0, not with a relative of root path. Does this problem Flowfuse related? or all people that develop third party nodes?
What do you think? Do you think that if FlowFuse solve the #1 all will work perfectly? thanks a lot for your help
From your description I am convinced that the cause is that described in #1615 and that a fix for that would fix your issues. Please add a comment on that issue.
I have read through this a couple times, and I am still missing something: Was there an answer on how to use a root location on the nginx reverse proxy for dashboard 2?
I would like to set up the nginx reverse proxy to have the root location location / to point to http://node-red:1880/dashboard. However, I only get a "blank page" when I do that. I can set ANY OTHER sub-path and it works fine; e.g. location /helpme (thanks to the above code from @ortegafernando !)
Am I just missing an nginx directive or is this the problem that's part of the backlog here or something else...?
My nginx.conf file:
server {
listen 80;
server_name _; # This will match any hostname
# Node-RED
location /nr/ {
proxy_pass http://node-red-tm:1880/;
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;
# WebSocket support
proxy_http_version 1.1;
proxy_cache_bypass $http_upgrade;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
#new nodered dashboard 2.0
location / {
proxy_pass http://node-red-tm:1880/dashboard/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Referer "";
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_cache_bypass $http_upgrade;
}
#old nodered ui
location /ui/ {
proxy_pass http://node-red-tm:1880/ui/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
** Additional context ** I do, when I load it as root momentarily see this Loading ... icon. But only for a millisecond:
Let me know if I can share anything else about this.
Edit: Actually, with the location as root, if I explicitly type out the PATH of the Dashboard 2 PAGE, then that content will load; e.g. http://myhost/home for the home page will load the content. If I leave off the path for home; i.e. make it root, it has the same non-loading issue.