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 | > firstname.lastname@example.org 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.