Node-RED Standalone Executable

Hello all,

I am curious about the best way to package a Node-RED application for deployment as a standalone executable. The goal is to be able to develop a Node-RED application on a Raspberry Pi and once it is finished, I can create an executable file that can be copied/deployed on another Pi that doesn't have Node-RED installed. After doing some research I have stumbled across three options that are promising:

  1. Electron-Package-Manager
  2. Running in a Docker container
  3. Using the pkg tool

Just from the quick research I did on each option it appears the pkg tool would be the easiest and most suitable for my current situation if I can get it to work. The main disconnect I'm having is that the package.json file needs a "main entry" point for the application and it appears to be looking for a JavaScript file, usually named index.js. This doesn't seem to be the case with Node-RED as I haven't been able to find it anywhere in my .node-red directory or subdirectories.

I'm willing to try other options if there is a better way to accomplish what I'm trying to do. Docker seems to be the most popular choice, but it requires installing Docker on the second Pi (which isn't a deal breaker), but ideally, I wouldn't have to install any other software besides the standalone executable and the default RPI OS installation.

I haven't spent enough time looking into Electron, but it appears to be a more complicated (different) way of accomplishing the same thing as the pkg tool. I briefly read through the ReadMe on this page GitHub - dceejay/electron-node-red: Electron Node-RED template but perhaps it is exactly what I'm looking for.

Thank you in advance for ideas and help!

There is already, I believe, at least one electron packaged version of Node-RED. And of course, there is also an official Docker container, though you would need to do something with the default settings/flow/etc that exist in the /data mount that the container uses as its userDir.

By Electron packaged version of Node-RED do you mean a script or process of packaging a node red project? Can you point me in the direction of more information?

  1. Install Node-RED
mkdir NodeRED
cd NodeRED
npm install node-red
  1. Any node you want 'pre-packaged' install into NodeRED/node_modules/ (just run the installers from within the NodeRED dir

  2. Add the following to package.json

"name": "Node-RED",
"bin": "node_modules/node-red/red.js",
"pkg":{
   "assets": ["./node_modules/**/*.*"]
}
  1. Run the following pkg . (make sure pkg is installed globally - at least I have)

  2. You can now start the single executable with everything embedded, the name will become the name of the executable

Node-RED --userDir /Some/dir

I have done this a few times - and works quite well.

1 Like

This is the route I have spent the most time trying to figure out. If I installed Node-RED using the official script, and am also using the Projects feature, how would the instructions change? Also can I manually add dependencies to the package.json file? I usually install additional nodes through the palette manager.

For creating portable binaries of Node RED, I (as per my post):

  • Install Node RED in my directory that I will be working in
  • Install any modules in the same directory, that I want 'hard installed' - as if it comes with Node RED by default
  • Patch my package.json
  • Run pkg

I have not done this for the standard install, so not sure how it will react - I have never used the standard installer, so my knowledge with it, is extremely limited.

ideally you will patch the package.json file and run pkg in the folder that contains the installed Node RED location - but that will package up any other global Node app you have installed (not just Node RED)

I see, and your method allows you to move the standalone executable to a raspberry pi that doesn't have node-RED installed?

Correct.

Providing - the target platform is of the same platform your run pkg.
pkg will embed the Node runtime of the platform

EDIT:
you can use this, to ensure the correct executable

pkg . -t host <- will use the host platform for the binary output. But I think not including -t will still produce a Linux executable.

The executable will still create the $USER/.node-red dir, but you can pass the normal arguments to it, if you wanted to ship a flow with your executable

Good to know. I don't want to sound like a pest, but could you show me an example of a complete package.json file after you have made your modifications?

I can soon, not at a computer right now.

Ok I would appreciate it. Thank you for what you have already shared as well.

@jgreenmt

Start to Finnish (I have just tested this on OSX)

Create working directory, install Node RED

mkdir NodeRED
cd NodeRED
npm install node-red

Hard Install some nodes (using dashboard as example)

npm install node-red-dashboard

Modify package.json (NodeRED/package.json)

/* Before */
{
  "dependencies": {
    "node-red": "^3.0.2",
    "node-red-dashboard": "^3.4.0"
  }
}

/* After */
{
 "name": "Node-RED",
 "bin": "node_modules/node-red/red.js",
 "pkg":{
    "assets": ["./node_modules/**/*.*"]
  },
  "dependencies": {
    "node-red": "^3.0.2",
    "node-red-dashboard": "^3.4.0"
  }
}

Build Binary (it will also embed any nodes you installed in step 2)

pkg . -t host

Run Binary (or move it to a new system) <- only binary is needed

Node-RED --userDir /some/dir

There are pros and cons to hard installing nodes.

  • No need to transport large node_module folders
  • Can't remove or update hard installed nodes (as they are embdded)

So hard installing nodes is optional, but for nodes you need, you will need to install them normally if not embedding them

4 Likes

Great! This is very helpful. The missing piece has always been the part of package.json to start node-RED. All the examples I have seen want a section called "main" and it usually contains index.js or something similar. I believe this is more of a Node.js application. It seems like the "bin" section takes care of that.

I am going to try to get this to work using my current install of Node-RED and the Projects feature. If I am not able to get it to work, I will follow your instructions precisely. Either way, I will post my results.

I'm also still interested in the electron solution if anyone has any experience they'd like to share, or can point me to an explanation of how it works?

One more question I thought of, if I wanted to build an executable to run on Windows, but I developed it on a Raspberry Pi, is it really as easy as just changing the target section of the package.json file?

it is possible by setting -t to win64 (I believe) - you will need to research.

I don't specify it In the package file

But do be cautions:

Some Node modules are "compiled" during install - so they will not be binary compatible
(Even if the resulting "parent" binary that encapsulate it is)

Here is the result from my steps (I have deleted all folders) - to remove the templated install: for proof I guess :sweat_smile:

I should be using --userDir not --userDIR :innocent:

Apr-26-2023 22-25-25

2 Likes

It turns up with an Internet search.

Can you point me to some specifics on how to do this? I would like, at least, to enable projects and open a port for mqtt. I have pulled the docker image into VS Code, but don't know what to do next.

I don't want to hijack this thread, but this is a neat solution. Is it also possible to include a flow file+credentials+settings and having it execute immediately with (customized) settings ? ie. I want to hide the gui and just have a flow running directly from the executable.

Hi @bakman2,

Yes you can :nerd_face:
But there are a few things to watch for and do.

  • You wont be able to make changes to the flow, trying to
    deploy will complain of a Read Only File System (See my image)

  • You need to set the flows file and settings file as augments, when running the executable

  • The virtual file system starts at /snapshot/<Folder-Name> or c:\snapshot\<Folder-Name> for win

With all that in mind...
Lets assume we are working in a directory called NR

  • The folder in which you installed Node RED (I.e your working directory) add a folder of say config

  • Add this folder to the assets section of package.json

"pkg":{
    "assets": ["./node_modules/**/*.*", "./config/**/*.*"]
  },
  • Start node red normally to create your flows,
    BUT pass in an arg of --userDir <Location of Config Dir>

  • Run the normal pkg command

Now then.....

To run the executable and have it use the embedded settings file and flows....

Node-RED-Executable --settings /snapshot/NR/config/settings.js /snapshot/NR/config/flows.json

Note: you will still need to set a userDir or let it use default, as Node RED will try and create it each time, and if setting userDir to an embdded location, it will crash trying to create the Dir

1 Like

Seems that it IS possible to have a container to host a writable file system. But any changes are written to the host filing system rather than the container (since containers are mostly read-only).

You can use an overlay filing system to do that in Linux. I doubt it is possible in Windows.

I only use Docker for the most basic of things so I'm no expert but some searching turned up a number of posts about this.

Maybe start with this backgrounder: What are Docker Storage Drivers and Which Should You Use? (howtogeek.com)