-
-
Notifications
You must be signed in to change notification settings - Fork 86
NGINX & Proxying Node RED
Please see the updated article in the Tech Docs.
This article assumes the use of Debian Buster (10). It should probably also work on Rasbian Buster. It also assumes that you already have Node-RED installed and working (and therefore Node.js) and a working uibuilder node.
WARNING This configuration guide does NOT cover SECURITY of your server. Do not expose a server to the Internet without having a properly configured firewall and until you have hardened the OS configuration of your server.
# Update the catalogue of installable apps
sudo apt update
# Get all installed aps up-to-date
sudo apt upgrade
Next follow the instructions at https://nginx.org/en/linux_packages.html#Debian to make sure that you get a decent version of NGINX. Note that I don't personally advise installing the version that is included in the standard Debian libraries as these are usually quite a long way behind current.
Choose the mainline
version for the latest features (might occasionally be slightly less stable) or the stable
version for production use.
As at the time of writing this:
# Install the prerequisites:
sudo apt install curl gnupg2 ca-certificates lsb-release
# To set up the apt repository for stable nginx packages, run the following command:
echo "deb http://nginx.org/packages/debian `lsb_release -cs` nginx" | sudo tee /etc/apt/sources.list.d/nginx.list
# If you would like to use mainline nginx packages, run the following command instead:
#echo "deb http://nginx.org/packages/mainline/debian `lsb_release -cs` nginx" | sudo tee /etc/apt/sources.list.d/nginx.list
# Set up repository pinning to prefer our packages over distribution-provided ones:
echo -e "Package: *\nPin: origin nginx.org\nPin: release o=nginx\nPin-Priority: 900\n" | sudo tee /etc/apt/preferences.d/99nginx
# Next, import an official nginx signing key so apt could verify the packages authenticity. Fetch the key:
curl -o /tmp/nginx_signing.key https://nginx.org/keys/nginx_signing.key
# Verify that the downloaded file contains the proper key:
gpg --dry-run --quiet --import --import-options import-show /tmp/nginx_signing.key
# The output should contain the full fingerprint 573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62 as follows:
#
# pub rsa2048 2011-08-19 [SC] [expires: 2024-06-14]
# 573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62
# uid nginx signing key <[email protected]>
# Finally, move the key to apt trusted key storage (note the "asc" file extension change):
sudo mv /tmp/nginx_signing.key /etc/apt/trusted.gpg.d/nginx_signing.asc
# To install nginx, run the following commands:
sudo apt update
sudo apt install nginx
You should now be able to see that NGINX is running:
# Show the status
sudo systemctl status nginx
# Show the log
sudo journalctl -u nginx
# Restart/Start/Stop
sudo systemctl restart nginx
At this point, you can open the default web page at http://<server-ip-or-domain-name>/
.
The configuration for NGINX lives at /etc/nginx/
. There is a default nginx.conf
file there that tells you where logs are stored should you need them though using journalctl
is generally preferable for viewing. It is recommended to leave this file alone.
There is also a /etc/nginx/conf.d/default.conf
file that defines a default simple root website. You can either repurpose this if you don't want to create any other sites, or you can create your own .conf file.
NOTE that, by default, NGINX runs as user and group nginx
. You should create files owned by this user/group when you want the server to serve them. Configuration files must be owned by root:root
.
In this example, we will create a config file /etc/nginx/conf.d/nodered.conf
. This will leave the default root site as it is, if you aren't using a default root site, you should remove that configuration.
I will assume the following Node-RED settings that illustrate a number of features:
- Node-RED is running under the user id that you log into the server with. Note that this is a bad idea for production use, particularly if exposing to the Internet, move Node-RED to use its own user/group and make sure that all files are owned by that user/group. Don't allow that user id to log in to the server.
- The Node-RED Editor page is moved to
http://<server-ip-or-domain-name>:1880/red
- The Node-RED Dashboard page is:
http://<server-ip-or-domain-name>:1880/ui
- Node-RED is installed locally not globally to
~/nrmain
, the userDir folder is set to~/nrmain/data
. - The Node-RED static resource folder is in
~/nrmain/data/public/
This file should be owned by root:root (use sudo
to edit it).
#proxy for node-red @ port :1880
# Redirect all http to https
server {
listen 80 default_server;
listen [::]:80;
server_name _;
return 301 https://$host$request_uri;
}
# Proxy Node-RED
server {
# Ports to listen on.
listen 443 ssl http2;
listen [::]:443 ssl http2 ipv6only=on;
# If you want to limit this config to specific (sub)domain names:
server_name example.com nr.example.com;
# Specify the public cert and private key
ssl_certificate /path/to/fullchain.cer;
ssl_certificate_key /path/to/privatekey.key;
# Require safe TLS protocols only
ssl_protocols TLSv1.1 TLSv1.2;
# Only use secure encryption ciphers
ssl_ciphers EECDH+CHACHA20:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
# Configure for Strict Transport Security (HSTS)
add_header Strict-Transport-Security "max-age=15768000; includeSubDomains" always;
#location = /robots.txt {
# add_header Content-Type text/plain;
# return 200 "User-agent: *\nDisallow: /\n";
#}
# Specify the actual URL path to proxy
# NOTE: To change this to something other than `/`, you have to add a rewrite rule:
# # Assuming you want to use `location /red/`
# rewrite ^/red/(.*)$ /$1 break;
location / {
# Change the IP address and port to match your instance of Node-RED
# Note that you don't need to make Node-RED serve https if it is on the same
# server as NGINX
proxy_pass https://127.0.0.1:1880;
# If using a location other than just `/`, we need to rewrite all of the /red/ URLS to remove the `red` part
# If we don't, the node.js server won't understand the requests
#rewrite ^/red/(.*)$ /$1 break;
# If you only want to expose the Node-RED Dashboard instead of the whole of Node-RED ...
# of course, you can do this for any Node-RED path, such as a specific uibuiler URL.
#rewrite ^/(.*)$ /ui/$1 break;
#Defines the HTTP protocol version for proxying by default it it set to 1.0.
#For Websockets and keepalive connections you need to use the version 1.1
proxy_http_version 1.1;
#Sets conditions under which the response will not be taken from a cache.
proxy_cache_bypass $http_upgrade;
#These header fields are required if your application is using Websockets
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
#The $host variable in the following order of precedence contains:
#hostname from the request line, or hostname from the Host request header field
#or the server name matching a request.
proxy_set_header Host $host;
#Forwards the real visitor remote IP address to the proxied server
proxy_set_header X-Real-IP $remote_addr;
#A list containing the IP addresses of every server the client has been proxied through
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
#When used inside an HTTPS server block, each HTTP response from the proxied server is rewritten to HTTPS.
proxy_set_header X-Forwarded-Proto $scheme;
#Defines the original host requested by the client.
proxy_set_header X-Forwarded-Host $host;
#Defines the original port requested by the client.
proxy_set_header X-Forwarded-Port $server_port;
}
# You can create multiple locations with different paths.
# You will need to do this if you are running uibuilder on its own webserver (and so with a different port).
}
After editing the file, check for configuration errors: sudo nginx -t
, restart NGINX: sudo systemctl restart nginx
and check that that it started OK: sudo journalctl -u nginx
.
-
Remember that, if you are proxying URL's, not all of the links in the Node-RED editor will work. You will have to mentally translate them to their new locations.
-
If you are using proxying to help give additional security, remember to block access to ALL TCP PORTS except the specific ones you have proxied. Do this at the router/firewall level if you still need to give people on your internal network access to the other ports.
Please feel free to add comments to the page (clearly mark with your initials & please add a commit msg so we know what has changed). You can contact me in the Discourse forum, or raise an issue here in GitHub! I will make sure all comments & suggestions are represented here.
-
Walkthrough 🔗 Getting started
-
In Progress and To Do 🔗 What's coming up for uibuilder?
-
Awesome uibuilder Examples, tutorials, templates and references.
-
How To
- How to send data when a client connects or reloads the page
- Send messages to a specific client
- Cache & Replay Messages
- Cache without a helper node
- Use webpack to optimise front-end libraries and code
- How to contribute & coding standards
- How to use NGINX as a proxy for Node-RED
- How to manage packages manually
- How to upload a file from the browser to Node-RED
-
Vanilla HTML/JavaScript examples
-
VueJS general hints, tips and examples
- Load Vue (v2 or v3) components without a build step (modern browsers only)
- How to use webpack with VueJS (or other frameworks)
- Awesome VueJS - Tips, info & libraries for working with Vue
- Components that work
-
VueJS v3 hints, tips and examples
-
VueJS v2 hints, tips and examples
- Dynamically load .vue files without a build step (Vue v2)
- Really Simple Example (Quote of the Day)
- Example charts using Chartkick, Chart.js, Google
- Example Gauge using vue-svg-gauge
- Example charts using ApexCharts
- Example chart using Vue-ECharts
- Example: debug messages using uibuilder & Vue
- Example: knob/gauge widget for uibuilder & Vue
- Example: Embedded video player using VideoJS
- Simple Button Acknowledgement Example Thanks to ringmybell
- Using Vue-Router without a build step Thanks to AFelix
- Vue Canvas Knob Component Thanks to Klaus Zerbe
-
Examples for other frameworks (check version before trying)
- Basic jQuery example - Updated for uibuilder v6.1
- ReactJS with no build - updated for uibuilder v5/6
-
Examples for other frameworks (may not work, out-of-date)
-
Outdated Pages (Historic only)
- v1 Examples (these need updating to uibuilder v2/v3/v4/v5)