1/30/2023
Grafana + InfluxDB + MQTT — IoT dashboard from scratch
TL;DR: Three components of the stack: Mosquitto broker, InfluxDB as the time-series DB, Grafana as the visualization layer. Everything in Docker Compose, ready in 2 hours.
IoT system monitoring starts with a question: how do I know what my sensor was doing two hours ago? Log files aren’t enough, and a relational database overcomplicates time-series queries. This is where the Mosquitto + InfluxDB + Grafana stack comes in — mature, well-documented tools that together create a complete pipeline from sensor to dashboard chart.
Why this stack
InfluxDB is optimized for time series. When a temperature sensor sends a reading every 10 seconds, each record has a timestamp and a value — exactly the schema InfluxDB handles natively. A query for “average temperature over the last hour grouped by 5 minutes” is a single line in the Flux language, whereas in SQL it would require complex time window operations.
Grafana has a native connector for InfluxDB 2.x and hundreds of pre-built dashboards on the marketplace (grafana.com/grafana/dashboards). For popular devices — Zigbee sensors, Shelly, ESP32 — you can often find a ready-to-import dashboard in 30 seconds.
Docker Compose
The full configuration starts three services:
version: '3.8'
services:
mosquitto:
image: eclipse-mosquitto:2
ports:
- "1883:1883"
volumes:
- ./mosquitto/config:/mosquitto/config
- ./mosquitto/data:/mosquitto/data
influxdb:
image: influxdb:2.7
ports:
- "8086:8086"
environment:
- DOCKER_INFLUXDB_INIT_MODE=setup
- DOCKER_INFLUXDB_INIT_USERNAME=admin
- DOCKER_INFLUXDB_INIT_PASSWORD=haslo_admin
- DOCKER_INFLUXDB_INIT_ORG=myorg
- DOCKER_INFLUXDB_INIT_BUCKET=iot
- DOCKER_INFLUXDB_INIT_ADMIN_TOKEN=moj_token_api
volumes:
- influxdb_data:/var/lib/influxdb2
grafana:
image: grafana/grafana:latest
ports:
- "3000:3000"
environment:
- GF_SECURITY_ADMIN_PASSWORD=haslo_grafana
volumes:
- grafana_data:/var/lib/grafana
volumes:
influxdb_data:
grafana_data:
After docker compose up -d, InfluxDB is available on port 8086 and Grafana on port 3000. Mosquitto requires a mosquitto.conf config file with listener 1883 and allow_anonymous true (or user configuration for production).
Node-RED as an MQTT → InfluxDB bridge
Rather than writing your own Python script to subscribe to MQTT and write to InfluxDB, it’s worth using Node-RED. The visual flow-based editor handles both protocols through built-in nodes, and data transformation (JSON parsing, field renaming) happens without a single line of code.
Node-RED can be added to the same docker-compose.yml as a fourth service using the nodered/node-red:latest image. Once you install the node-red-contrib-influxdb nodes and the built-in mqtt in node, you’re ready to go.
Example flow
A typical flow looks like this. The mqtt in node subscribes to the topic sensors/temperatura/salon and receives a payload in the format {"value": 21.3, "humidity": 45}. A function node parses the JSON and transforms the data into InfluxDB format:
const data = JSON.parse(msg.payload);
msg.payload = [
{
measurement: "temperatura",
fields: { value: data.value, humidity: data.humidity },
timestamp: new Date()
}
];
return msg;
The influxdb out node writes the data to the iot bucket in the myorg organization. The connection is configured via the URL http://influxdb:8086 and an API token.
Grafana datasource and dashboard
In Grafana, go to Configuration → Data Sources → Add data source → InfluxDB. Select Flux as the query language and enter the URL http://influxdb:8086, organization myorg, bucket iot, and the API token.
Example Flux query for a temperature chart over the last 24 hours:
from(bucket: "iot")
|> range(start: -24h)
|> filter(fn: (r) => r._measurement == "temperatura")
|> filter(fn: (r) => r._field == "value")
|> aggregateWindow(every: 5m, fn: mean, createEmpty: false)
You can add an alert on the panel: if the temperature exceeds 30°C for 5 minutes — send a notification via email or Telegram.
Summary
The Mosquitto + InfluxDB + Grafana stack runs in production with hundreds of sensors. It requires no external cloud services or subscriptions. Operating costs are server electricity and setup time — everything is open source and self-hosted. For new IoT projects, this is the starting point you should build from.