Node-Red: Docker Setup
There are a number of tutorials out there that will tell you how to get a basic node-red setup running on a Raspberry-Pi, and more than a few with a one-liner docker setup. These leave you with something that works but is less reliable and harder to maintain.
Using Docker means that everything you needed to install or setup to get things running is documented and repeatable. This means if a piece of hardware fails, we want to upgrade the OS on the host machine or move everything to a new machine we should be able to do so without mysterious setup problems.
If you want to follow along, here are my installation notes:
- Raspberry Pi 4 with Raspbian image (Debian 10)
- Docker is installed (link)
- Docker-compose is installed (apt-get install docker-compose)
- Assumes you are logged in as the "pi" user by default. If you use a different login you may need to adjust paths, etc.
- Directory /home/pi/nodered/data is created and the following files are added to the ~/nodered directory.
FROM nodered/node-red:latest
USER root
RUN addgroup node-red dialout
USER node-red
version: "3"
services:
node-red:
container_name: nodered
build: .
environment:
- "TZ=America/Los_Angeles" # offset = -08:00 / DST -07:00
ports:
- "1880:1880/tcp" # main node-red web interface
- "4992:4992/udp" # flex radio discovery protocol
- "4993:4993/udp" # flex radio VITA-49 API
- "4994:4994/tcp" # flex radio TCP/IP API
devices:
- dev/ttyUSB0:/dev/ttyKPA500
- dev/ttyUSB1:/dev/ttyKAT500
networks:
- node-red-net
volumes:
- node-red-data:/data
- node-red-usr:/usr/src/node-red
restart: always
volumes:
node-red-data:
driver: local
driver_opts:
o: bind
type: none
device: /home/pi/nodered/data
node-red-usr:
driver: local
driver_opts:
o: bind
type: none
device: /home/pi/nodered/usr
networks:
node-red-net:
There are a few things to note in the example above:
- Additional ports are opened. I plan on using node-red with my FlexRadio, so I've exposed ports 4992, 4993, and 4994 in order for node-red to be able to communicate with the radio (reference).
- The local USB devices USB0 and USB1 are mapped to ttyKPA500 and ttyKAT500. I use these mapped names in my flow so that if the devices change on the physical hardware, I can remap them in one place rather than all over creation. The extra step of adding the node-red user to the dial-out group so the USB ports are accessible is handled in the Dockerfile.
- Data is stored in ~/nodered/data and ~/nodered/usr. You'll need to create the directory listed in the device options (reference). Every bit of data stored for your node-red setup will be kept in the ~/nodered directory, which makes porting everything to another machine and backing things up super simple.
- Node-red will automatically restart itself as needed. If you manually stop the docker container, the process won't restart (you'll need to issue docker-compose up again from the nodered directory) but otherwise it will start whenever the machine restarts or if the process crashes.
Once you have everything completed above, you should be able to run docker-compose build and then docker-compose up to build and start the node-red docker container.
pi@hampi:~/nodered $ sudo docker-compose build
node-red uses an image, skipping
pi@hampi:~/nodered $ sudo docker-compose up
Pulling node-red (nodered/node-red:latest)...
latest: Pulling from nodered/node-red
80ca8924263d: Pull complete
497280a25128: Pull complete
e67910a1bf8f: Pull complete
6702d9426491: Pull complete
bdc2f080d2b6: Pull complete
b0bc8c8ba64c: Pull complete
59b49981ff35: Pull complete
fde372666cea: Pull complete
8c6a67b5b69a: Pull complete
5b23b11fb083: Pull complete
82a0cb99b35e: Pull complete
904561977419: Pull complete
7e32de713309: Pull complete
Digest: sha256:2232141045a2702818855675905f52c982fee5f5c30c0dbfad5607e65ec64701
Status: Downloaded newer image for nodered/node-red:latest
Creating nodered_node-red_1 ... done
Attaching to nodered_node-red_1
node-red_1 |
node-red_1 | > node-red-docker@2.1.4 start /usr/src/node-red
node-red_1 | > node $NODE_OPTIONS node_modules/node-red/red.js $FLOWS "--userDir" "/data"
node-red_1 |
node-red_1 | 31 Dec 01:34:53 - [info]
node-red_1 |
node-red_1 | Welcome to Node-RED
node-red_1 | ===================
node-red_1 |
node-red_1 | 31 Dec 01:34:53 - [info] Node-RED version: v2.1.4
node-red_1 | 31 Dec 01:34:53 - [info] Node.js version: v14.18.2
node-red_1 | 31 Dec 01:34:53 - [info] Linux 5.10.63-v7l+ arm LE
node-red_1 | 31 Dec 01:34:54 - [info] Loading palette nodes
node-red_1 | 31 Dec 01:34:55 - [info] Settings file : /data/settings.js
node-red_1 | 31 Dec 01:34:55 - [info] Context store : 'default' [module=memory]
node-red_1 | 31 Dec 01:34:55 - [info] User directory : /data
node-red_1 | 31 Dec 01:34:55 - [warn] Projects disabled : editorTheme.projects.enabled=false
node-red_1 | 31 Dec 01:34:55 - [info] Flows file : /data/flows.json
node-red_1 | 31 Dec 01:34:55 - [warn]
node-red_1 |
node-red_1 | ---------------------------------------------------------------------
node-red_1 | Your flow credentials file is encrypted using a system-generated key.
node-red_1 |
node-red_1 | If the system-generated key is lost for any reason, your credentials
node-red_1 | file will not be recoverable, you will have to delete it and re-enter
node-red_1 | your credentials.
node-red_1 |
node-red_1 | You should set your own key using the 'credentialSecret' option in
node-red_1 | your settings file. Node-RED will then re-encrypt your credentials
node-red_1 | file using your chosen key the next time you deploy a change.
node-red_1 | ---------------------------------------------------------------------
node-red_1 |
node-red_1 | 31 Dec 01:34:55 - [info] Server now running at http://127.0.0.1:1880/
node-red_1 | 31 Dec 01:34:55 - [info] Starting flows
node-red_1 | 31 Dec 01:34:55 - [info] Started flows
From here you should be able to point a browser at the machine running node-red and be greeted with a fresh node-red installation. In the above example this would be http://hampi:1880
If you haven't already found the node-red ham radio group on Groups.io, go join!
I'll publish more of my journeys with node-red to hopefully help others who are just getting started with it (like me). Once you are into a project it's easy to forget how you got there.