How to Install Node-RED (Visual Automation for Home Assistant, MQTT and Everything Else)

Home Assistant's automation editor is fine for "lights on at sunset". When the logic grows — only if someone's home, not twice within five minutes, wait for the door to close, then message the right person — a drawing beats a form. Node-RED is that drawing: nodes for triggers, conditions, delays and actions, wired together on a canvas, with Home Assistant, MQTT, HTTP, Telegram and hundreds of other things as nodes. It's also a general-purpose glue tool, like n8n (tutorial 77) with a smart-home accent.
Quick reference
| Task | What |
|---|---|
| Folder | ~/docker/nodered/compose.yaml |
| Editor | http://server-ip:1880 |
| Lock the editor | adminAuth in data/settings.js with a bcrypt hash |
| Home Assistant nodes | Manage palette → Install → node-red-contrib-home-assistant-websocket |
| HA access token | HA profile → Security → Long-lived access tokens |
| Export flows | ☰ → Export → All flows (JSON) |
1. The compose file
mkdir -p ~/docker/nodered/data && cd ~/docker/nodered
sudo chown -R 1000:1000 data
nano compose.yaml
services:
nodered:
image: nodered/node-red:latest
container_name: nodered
ports:
- "1880:1880"
environment:
TZ: Europe/London
volumes:
- ./data:/data
restart: unless-stopped
docker compose up -d
sudo ufw allow from 192.168.1.0/24 to any port 1880
2. Lock the editor first
By default anyone on the network can edit (and therefore run anything on the server). Make a password hash:
docker compose exec nodered node -e "console.log(require('bcryptjs').hashSync(process.argv[1], 8))" 'your-password'
Then in data/settings.js, find adminAuth (commented out) and set:
adminAuth: {
type: "credentials",
users: [{ username: "john", password: "$2a$08$...the hash...", permissions: "*" }]
},
docker compose restart nodered. The editor now asks for a login.
3. Connect Home Assistant
In the editor: ☰ → Manage palette → Install, search node-red-contrib-home-assistant-websocket, install. Drag any Home Assistant node onto the canvas, double-click, Server → Add new: URL http://192.168.1.50:8123, and a long-lived access token from your HA profile (Security tab). Deploy. The nodes now autocomplete every entity in your home.
Add an MQTT broker the same way on the mqtt-in node (tutorial 96) for devices that don't go through HA.
4. A first flow worth having
"Hallway motion at night turns on the light for two minutes, but not if someone switched it off within the last five":
- events: state node — entity binary_sensor.hallway_motion, to state on.
- time range node — 22:00 to 06:00 (from node-red-contrib-time-range-switch).
- current state node — light.hallway — only continue if it's off.
- call service node — light.turn_on, light.hallway, brightness 30%.
- delay 2 minutes → call service light.turn_off.
- A second events: state on the light going off by the switch → a change node that sets a flow variable manual_off = now; node 3 becomes a function node checking the variable is older than five minutes.
Every node shows its last output under it; the debug sidebar shows every message. Wiring it is faster than reading about it.
5. The rest of the toolbox
- inject (manual trigger / cron), switch (if/else), change (set values), delay / trigger (debounce, rate-limit), function (a few lines of JavaScript when needed).
- http request — any API; http in — your own webhook endpoints.
- telegram, ntfy (via http request), email.
- Dashboard 2.0 palette — buttons, gauges and charts on a phone page, no HA needed.
- node-red-contrib-ui-led, Shelly, Sonos, Zigbee2MQTT-specific nodes: a rich palette.
6. Back it up and version it
Flows live in data/flows.json; credentials encrypted in data/flows_cred.json with a key in data/.config.runtime.json. Back up the whole data folder, and turn on ☰ → Settings → Projects to keep flows in a git repository (push it to Gitea, tutorial 45).
Troubleshooting
HA nodes show "disconnected". Token expired or wrong URL; the HA address must be reachable from inside the container (use the LAN IP, not localhost).
Flow fires twice. Two triggers, or state → same state. Add a filter (RBE) node, or check "ignore state changes to same state".
Lost the editor password. Delete the adminAuth block from settings.js, restart, set it again.
"Permission denied" on /data. The folder must be owned by UID 1000.
Wrapping up
One container, lock the editor, install the Home Assistant palette, paste a token. From then on any automation you can describe in a sentence you can draw in a minute, and debug by watching the messages flow. Keep flows in Projects and the drawing is backed up too.
