We’re continuing where we left off after Part 4: Mosquitto Docker Container.
In this Part 4, we’ll be adding Node-RED, which will give us a visual and feature-rich method for automating stuff. This is a personal preference and you may decide not to do this and stick to Home Assistant Automations instead.
We expand our docker-compose.yaml with the config for the Node-RED container.
services:
[...]
nodered:
container_name: nodered
image: nodered/node-red
restart: unless-stopped
ports:
- "1880:1880/tcp"
environment:
- TZ=Europe/Brussels
volumes:
- /opt/nodered/data:/data
depends_on:
- homeassistant
- mosquitto
Because our Node-RED automations are reliant on Home Assistant and we may be doing some stuff over MQTT as well, we want to make sure our HA Container and Mosquitto broker are running.
If we now launch the Node-RED container using docker-compose up -d nodered you might notice you’re unable to open the web interface at http://<ip.of.our.box>:1880.
Checking the logs in Portainer or by running docker logs nodered, you may notice file permissions errors:
docker logs nodered
Error: EACCES: permission denied, copyfile '/usr/src/node-red/node_modules/node-red/settings.js' -> '/data/settings.js'
at Object.copyFileSync (node:fs:2817:3)
at copyFile (/usr/src/node-red/node_modules/fs-extra/lib/copy/copy-sync.js:73:6)
at onFile (/usr/src/node-red/node_modules/fs-extra/lib/copy/copy-sync.js:59:25)
at getStats (/usr/src/node-red/node_modules/fs-extra/lib/copy/copy-sync.js:51:44)
at handleFilterAndCopy (/usr/src/node-red/node_modules/fs-extra/lib/copy/copy-sync.js:36:10)
at Object.copySync (/usr/src/node-red/node_modules/fs-extra/lib/copy/copy-sync.js:29:10)
at Object.<anonymous> (/usr/src/node-red/node_modules/node-red/red.js:129:20)
at Module._compile (node:internal/modules/cjs/loader:1105:14)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1159:10)
at Module.load (node:internal/modules/cjs/loader:981:32) {
errno: -13,
syscall: 'copyfile',
code: 'EACCES',
path: '/usr/src/node-red/node_modules/node-red/settings.js',
dest: '/data/settings.js'
}
node:internal/fs/utils:345
throw err;
^
This has to do with how the mapping of users inside and outside a Docker container works.
Our Docker volume for the data directory was created by (and is owned by) our rootuser, who’s ID are uid=0 gid=0. The nodered user inside the container, which owns the /data directory, however has different IDs: 1000:1000 (uid:gid). We can fix this by changing the ownership of the Docker volume to the user with the ID 1000:1000 by running sudo chown -R 1000:1000 /opt/nodered/data.
Docker should notice the change in permissions and will restart the container. If not, recreate the container from the Portainer interface.
We can now open the Node-RED interface at http://<ip.of.our.box>:1880.
As we did with Portainer in Part 3, we can add Node-RED to the sidebar of our Home Assistant dashboard using the panel-iframe. This makes it easier to access Node-RED.
Add the following lines to configuration.yaml:
panel_iframe:
portainer: # part 3
[...]
nodered:
title: Node-RED
icon: mdi:lan
url: http://192.168.10.106:1880/
require_admin: true
Restart Home Assistant via the Developer Tools menu and you’ll side Node-RED appear in the sidebar.

Node-RED accessible from the sidebar
In a minute we’ll setup Node-RED to interface with Home Assistant. To set up this connection, we will need a Long-Lived Access Token, so let’s grab one.
Click on your username at the bottom of the Home Assistant sidebar and scroll down in the Profile page untill you see the Long-Lived Access Tokens section.

Create long-lived access tokens
Click create token and enter a name (e.g. Node-RED) for the token in the pop-up window. Finally copy the access token and paste it somewhere safe as you won’t be able to retrieve the token afterwards.
Open the Node-RED interface either through the Home Assistant dashboard or by browsing to http://<ip.of.our.box>:1880.

Node-RED welcomes us
Feel free to go through the walkthrough.
First we need to add the Home Assistant nodes to Node-RED.
node-red-contrib-home-assistant-websocket.
Install HA Websockets in the Palette
Next we need to set up the connection between Node-RED and Home Assistant.
events: all node from the Home Assistant section to the editor.Add new server... next to Server and click the pencil icon.Home Assistant).Using the Home Assistant Add-on.http://<ip.of.our.box>:8123.

Setting up the HA server connection

Entering the server details
From now on, we’ll be able to communicate with Home Assistant from Node-RED. We can listen for state changes and call services exposed by Home Assistant and HA integrations.
You can choose to only deploy nodes that were added or modified so Node-RED doesn’t restart all flows when deploying.

Deploy in full, modified flows or modified nodes
Let’s also setup a connection from Node-RED to our MQTT broker so we can directly communicate with devices over MQTT from Node-RED.
I prefer to create an additional MQTT user for Node-RED. This will allow us to track communications coming from Node-RED in the Mosquitto logs.
Open a terminal window, connect to the Docker machine and run the following command:
docker exec -it mosquitto mosquitto_passwd /mosquitto/config/mqttuser nodered
# Enter a password
This setup is fairly similar to how we setup the Home Assistant connection. The main difference is that we don’t need to add a package as MQTT is support by default.
<ip.of.our.box>) and Port (1883) of our broker, and pick a Client ID or let Node-RED generate a random one.# wildcard.
Connecting with MQTT broker
And with this part done, we can now setup the most exciting and visually pleasing automation flows and communicate directly with our MQTT broker without HA in-between.
Curious to see what I’ll add to my system next? Keep an eye open for the next blog post(s).