Raspberry Pi

IOTstack on Raspberry Pi: Node-RED, InfluxDB and Grafana with a Cloud MQTT Broker

Use IOTstack to run Node-RED, InfluxDB and Grafana in Docker on a Raspberry Pi, skip the local Mosquitto container and connect Node-RED to an external cloud MQTT broker instead.

Docker containers for Node-RED InfluxDB and Grafana running on an iotstack raspberry pi connected to a cloud MQTT broker
Run this on your own MQTT brokerGet a private, managed MQTT broker on the Free plan and start from ready-made code samples.
Try it free Code samples No card required

An iotstack raspberry pi setup gives you Node-RED, InfluxDB and Grafana as Docker containers that you can rebuild, update and back up with a few commands. In this tutorial you will install IOTstack, select the containers you need, connect Node-RED to an external MQTT broker instead of a local Mosquitto container, store readings in InfluxDB and chart them in Grafana. By the end you will have a reproducible stack and a clear idea of what belongs on the Pi and what does not.

What IOTstack Is and Why It Helps

IOTstack is a community project that wraps Docker Compose in a menu. You pick services from a list, it generates a docker-compose.yml with sensible volumes and ports, and you start everything with one command. The benefits over installing each tool natively are real:

  • Isolation. Node-RED's Node.js version cannot conflict with anything else on the Pi.
  • Reproducibility. The whole stack is described in one file plus a volumes folder. Copy both to a new Pi and you are back in business.
  • Clean upgrades. Pull a newer image, recreate the container, and roll back if it misbehaves.

The menu offers a Mosquitto container too, and many guides install it by reflex. Think about whether you need it. A local broker only serves devices that can reach the Pi. If your sensors live in more than one place, if you want to reach data from your phone without opening ports, or if you simply do not want to maintain broker security yourself, an external broker is the better choice. Here we use the ConnectMQ cloud broker, and the Pi becomes a pure processing and storage node.

Service Container in this tutorial Port
Node-RED Yes 1880
InfluxDB 1.8 Yes 8086
Grafana Yes 3000
Portainer CE Optional 9000
Mosquitto No, replaced by a cloud broker n/a

Install IOTstack on the Raspberry Pi

Start from Raspberry Pi OS Lite or Desktop, 64-bit, fully updated. The IOTstack installer sets up Docker, the Compose plugin and the IOTstack folder in your home directory:

sudo apt update && sudo apt full-upgrade -y
curl -fsSL https://raw.githubusercontent.com/SensorsIot/IOTstack/master/install.sh | bash

The script may ask you to reboot so your user joins the docker group. After rebooting, check Docker works without sudo:

docker version
docker compose version

Then launch the menu:

cd ~/IOTstack
./menu.sh

Choose Build Stack, then use the space bar to select nodered, influxdb and grafana (and portainer-ce if you like a web UI for containers). When you select Node-RED, the menu offers add-on nodes. Tick node-red-contrib-influxdb and node-red-dashboard (or the newer Dashboard 2.0 package if listed). Leave mosquitto unselected. Exit the menu and start the stack:

cd ~/IOTstack
docker compose up -d
docker ps --format 'table {{.Names}}\t{{.Status}}\t{{.Ports}}'

All three containers should report Up. Data lives under ~/IOTstack/volumes/, one folder per service.

Create the InfluxDB Database

The influxdb service in IOTstack is InfluxDB 1.8, which uses InfluxQL and has no setup wizard. Create a database and a retention policy from inside the container:

docker exec -it influxdb influx
CREATE DATABASE sensors
CREATE RETENTION POLICY "ninety_days" ON "sensors" DURATION 90d REPLICATION 1 DEFAULT
SHOW DATABASES
exit

Containers in the same Compose project share a network and reach each other by service name. That is why Node-RED and Grafana will use http://influxdb:8086, not localhost.

Connect Node-RED to an External MQTT Broker

Open Node-RED at http://<pi-ip>:1880. Drag an mqtt in node onto the canvas and edit its server:

  • Server: broker.connectmq.com
  • Port: 1883 for testing on the public broker
  • Protocol: MQTT V5 (or 3.1.1)
  • Client ID: something unique and non-empty, for example iotstack-nr-5d02e8
  • Topic: connectmq/demo/5d02e8/+/climate
  • Output: a parsed JSON object

The public broker needs no credentials, so you can test right away. Remember that the free public MQTT broker is readable by anyone, which is why the topic contains a random segment. If you are new to Node-RED's MQTT nodes, the Node-RED MQTT tutorial covers the config node in depth.

The Node-RED Flow: MQTT to InfluxDB

Import the flow below with Menu, Import. It subscribes to every room's climate topic, extracts the room name from the topic and writes a point to InfluxDB.

[
  {
    "id": "mqttIn1",
    "type": "mqtt in",
    "name": "climate in",
    "topic": "connectmq/demo/5d02e8/+/climate",
    "qos": "1",
    "datatype": "json",
    "broker": "broker1",
    "nl": false,
    "rap": true,
    "rh": 0,
    "inputs": 0,
    "x": 140, "y": 100,
    "wires": [["toPoint1"]]
  },
  {
    "id": "toPoint1",
    "type": "function",
    "name": "to InfluxDB point",
    "func": "const room = msg.topic.split('/')[3];\nconst p = msg.payload;\nif (typeof p.t !== 'number') { return null; }\nmsg.measurement = 'climate';\nmsg.payload = [\n  { temperature: p.t, humidity: p.rh },\n  { room: room }\n];\nreturn msg;",
    "outputs": 1,
    "x": 360, "y": 100,
    "wires": [["influxOut1"]]
  },
  {
    "id": "influxOut1",
    "type": "influxdb out",
    "influxdb": "influxCfg1",
    "name": "write sensors",
    "measurement": "",
    "precision": "",
    "retentionPolicy": "",
    "x": 580, "y": 100,
    "wires": []
  },
  {
    "id": "broker1",
    "type": "mqtt-broker",
    "name": "ConnectMQ public",
    "broker": "broker.connectmq.com",
    "port": "1883",
    "clientid": "iotstack-nr-5d02e8",
    "autoConnect": true,
    "usetls": false,
    "protocolVersion": "5",
    "keepalive": "60",
    "cleansession": true
  },
  {
    "id": "influxCfg1",
    "type": "influxdb",
    "hostname": "influxdb",
    "port": "8086",
    "database": "sensors",
    "name": "IOTstack InfluxDB",
    "influxdbVersion": "1.x"
  }
]

The function node returns an array of two objects, fields first and tags second, which is the format node-red-contrib-influxdb expects for a single point with tags. Deploy, then publish a test reading:

mosquitto_pub -h broker.connectmq.com -p 1883 -i tester-5d02e8 -q 1 \
  -t connectmq/demo/5d02e8/office/climate -m '{"t":22.4,"rh":41}'

Check that it arrived:

docker exec -it influxdb influx -database sensors \
  -execute 'SELECT * FROM climate ORDER BY time DESC LIMIT 5'

Grafana on the IOTstack Raspberry Pi

Open Grafana at http://<pi-ip>:3000, log in with the default admin account and change the password. Add a data source:

  1. Connections, Data sources, Add, InfluxDB.
  2. Query language: InfluxQL.
  3. URL: http://influxdb:8086.
  4. Database: sensors. No user or password needed with the default IOTstack config.
  5. Save and test.

Create a dashboard with a Time series panel and this query:

SELECT mean("temperature") FROM "climate"
WHERE $timeFilter
GROUP BY time($__interval), "room" fill(none)

Enter $tag_room in the query editor's ALIAS field and you get one clearly labelled line per room. If you prefer InfluxDB 2 and Flux, IOTstack also offers an influxdb2 service; the Raspberry Pi Grafana InfluxDB tutorial shows the Flux side in detail.

Production: Private Broker Credentials and TLS

For real deployments, replace the public broker with a private one. On a hosted MQTT broker like ConnectMQ, you create a broker in the portal and receive a username, password and client ID. In Node-RED, edit the mqtt-broker config node:

  • Port 8883, tick Use TLS and add a TLS config with Verify server certificate enabled. ConnectMQ uses a Let's Encrypt certificate, so no custom CA file is needed.
  • Client ID: YOUR_CLIENT_ID. ConnectMQ binds client IDs to issued credentials, so use exactly the one shown in the portal.
  • Security tab: YOUR_USERNAME and YOUR_PASSWORD.

Node-RED stores credentials encrypted in flows_cred.json inside ~/IOTstack/volumes/nodered/data. Set a credentialSecret in settings.js in the same folder so the encryption key is stable across container rebuilds.

Backups and Updates

IOTstack's strength is that everything you care about is in two places: docker-compose.yml and volumes/. A simple routine:

  1. Stop the stack briefly with docker compose stop (or use IOTstack's backup scripts if you installed them).
  2. Archive the folder: sudo tar czf ~/iotstack-$(date +%F).tgz -C ~ IOTstack/docker-compose.yml IOTstack/volumes.
  3. Start again with docker compose up -d and copy the archive off the Pi.

To update images:

cd ~/IOTstack
docker compose pull
docker compose up -d
docker image prune -f

Pin image tags in docker-compose.yml for services where a surprise major upgrade would hurt, InfluxDB in particular.

Troubleshooting

Symptom Cause Fix
Node-RED MQTT node stays "connecting" Wrong port or TLS setting 1883 without TLS, 8883 with TLS
Node-RED shows "disconnected" right after connecting Duplicate client ID Each client needs its own ID
InfluxDB node error ENOTFOUND influxdb Host set to localhost Use the service name influxdb
Grafana "database not found" Database not created Run CREATE DATABASE sensors
Containers stop after reboot Restart policy missing IOTstack sets restart: unless-stopped, check the file

Get Started with ConnectMQ

Let IOTstack do the processing and let a managed broker handle the connections. Create a free account at app.connectmq.com, choose the Serverless plan with no credit card, and paste the generated credentials into your Node-RED config node. More Pi projects are collected in the Raspberry Pi MQTT tutorial.

Frequently Asked Questions

Do I need the Mosquitto container in IOTstack?

Only if every device is on the same local network and you want the broker on the Pi. With an external cloud broker, Node-RED subscribes over the internet and you avoid maintaining broker security on the Pi.

Which InfluxDB version does IOTstack use?

The influxdb service is InfluxDB 1.8 with InfluxQL, and a separate influxdb2 service provides version 2 with Flux. Pick one and stick with it, since the Node-RED and Grafana settings differ.

Can I run IOTstack on a 32-bit Raspberry Pi OS?

Some images still publish 32-bit builds, but support is shrinking. A 64-bit OS avoids most image compatibility problems.

How do I move IOTstack to a new Raspberry Pi?

Install IOTstack on the new Pi, stop it, then restore your docker-compose.yml and volumes folder and run docker compose up -d.

Related articles

Pico W vs Pico 2 W for MQTT: RP2040 vs RP2350 Performance, Memory and TLS

The Pico 2 W keeps the Pico W's footprint and Wi-Fi chip but swaps the RP2040 for the faster RP2350. This comparison looks at what that means for MQTT devices: CPU, memory, TLS, security features, software support, and which board to buy for which project.

8 min read

Raspberry Pi RFID MQTT Access Logging with the RC522 Reader

Wire an RC522 RFID reader to a Raspberry Pi, read tags in Python, check them against a local allowlist and publish every access attempt as an MQTT event that loggers, dashboards and alerting tools can consume.

7 min read

All articles →

Your private MQTT broker is a few clicks away

Create an account, get your broker credentials and connect your first device — no servers to install, patch or scale.