IoT Sensor Platform
IoT platform with EMQX MQTT broker, TimescaleDB for time-series, Telegraf collection, and Grafana
Overview
EMQX is a massively scalable, open-source MQTT broker built on Erlang/OTP that can handle millions of concurrent IoT device connections with sub-millisecond latency. As a distributed message broker implementing MQTT 3.1.1 and 5.0 protocols, EMQX excels at ingesting high-velocity sensor data from IoT devices, industrial equipment, and smart home systems. Originally developed by EMQ Technologies, it has become the backbone for IoT platforms requiring enterprise-grade reliability and horizontal scaling capabilities.
This IoT sensor platform combines EMQX's high-performance MQTT brokering with TimescaleDB's PostgreSQL-based time-series storage, creating a powerful data pipeline for sensor telemetry. Telegraf acts as the bridge, subscribing to MQTT topics from EMQX and writing structured time-series data into TimescaleDB's hypertables with automatic time-based partitioning. Grafana completes the stack by providing rich visualizations and alerting capabilities, connecting directly to TimescaleDB using standard PostgreSQL drivers for complex analytical queries across your sensor data.
This combination is ideal for IoT developers and system integrators who need PostgreSQL compatibility alongside time-series optimization, allowing them to join sensor data with relational information like device metadata, user accounts, or inventory systems. Unlike pure time-series databases, TimescaleDB's full SQL support enables complex analytics while EMQX handles the massive concurrent connection loads that industrial IoT deployments demand, making this stack perfect for smart building management, industrial monitoring, or large-scale sensor networks.
Key Features
- EMQX clustering support for horizontal scaling to millions of concurrent MQTT connections
- TimescaleDB hypertables with automatic time-based partitioning for optimal sensor data storage
- Built-in EMQX rule engine for real-time data processing and routing based on MQTT topics
- TimescaleDB continuous aggregates for pre-computed sensor data rollups and statistics
- EMQX WebSocket and MQTT-over-SSL support for browser-based IoT applications
- PostgreSQL compatibility allowing complex JOINs between sensor data and device metadata
- Telegraf's extensive input plugins supporting 200+ data sources beyond MQTT
- TimescaleDB compression achieving 90%+ storage reduction for historical sensor data
Common Use Cases
- 1Smart building management systems collecting temperature, humidity, and occupancy data from hundreds of sensors
- 2Industrial IoT monitoring for manufacturing equipment with predictive maintenance analytics
- 3Environmental monitoring networks tracking air quality, weather, and pollution across multiple locations
- 4Smart agriculture platforms monitoring soil moisture, temperature, and crop health sensors
- 5Fleet management systems tracking vehicle telemetry, GPS coordinates, and engine diagnostics
- 6Home automation platforms managing smart thermostats, security sensors, and energy monitors
- 7Retail analytics collecting foot traffic, temperature, and inventory sensor data across store chains
Prerequisites
- Minimum 4GB RAM recommended (2GB for TimescaleDB, 1GB for EMQX, 512MB for Grafana)
- Available ports: 1883 (MQTT), 5432 (PostgreSQL), 3000 (Grafana), 18083 (EMQX Dashboard)
- Basic understanding of MQTT protocol and topic structure for IoT device communication
- Familiarity with PostgreSQL and SQL queries for TimescaleDB data analysis
- Telegraf configuration knowledge for setting up MQTT consumer and PostgreSQL output plugins
- Understanding of time-series data concepts like retention policies and data aggregation
For development & testing. Review security settings, change default credentials, and test thoroughly before production use. See Terms
docker-compose.yml
docker-compose.yml
1services: 2 emqx: 3 image: emqx/emqx:latest4 container_name: emqx5 restart: unless-stopped6 ports: 7 - "1883:1883"8 - "8083:8083"9 - "8084:8084"10 - "${EMQX_DASHBOARD:-18083}:18083"11 environment: 12 - EMQX_NAME=emqx13 - EMQX_HOST=127.0.0.114 volumes: 15 - emqx_data:/opt/emqx/data16 - emqx_log:/opt/emqx/log1718 timescaledb: 19 image: timescale/timescaledb:latest-pg1520 container_name: timescaledb21 restart: unless-stopped22 ports: 23 - "${TIMESCALE_PORT:-5432}:5432"24 environment: 25 - POSTGRES_USER=${DB_USER}26 - POSTGRES_PASSWORD=${DB_PASSWORD}27 - POSTGRES_DB=iot28 volumes: 29 - timescaledb_data:/var/lib/postgresql/data3031 telegraf: 32 image: telegraf:latest33 container_name: telegraf34 restart: unless-stopped35 volumes: 36 - ./telegraf/telegraf.conf:/etc/telegraf/telegraf.conf:ro37 depends_on: 38 - emqx39 - timescaledb4041 grafana: 42 image: grafana/grafana:latest43 container_name: iot-grafana44 restart: unless-stopped45 ports: 46 - "${GRAFANA_PORT:-3000}:3000"47 environment: 48 - GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_PASSWORD:-admin}49 volumes: 50 - grafana_data:/var/lib/grafana51 depends_on: 52 - timescaledb5354volumes: 55 emqx_data: 56 emqx_log: 57 timescaledb_data: 58 grafana_data: .env Template
.env
1# IoT Sensor Platform2EMQX_DASHBOARD=180833TIMESCALE_PORT=54324GRAFANA_PORT=300056# Database7DB_USER=iot8DB_PASSWORD=iot_password910# Grafana11GRAFANA_PASSWORD=adminUsage Notes
- 1EMQX Dashboard at http://localhost:18083 (admin/public)
- 2MQTT broker at localhost:1883
- 3Grafana at http://localhost:3000
- 4Configure telegraf.conf for MQTT input and PostgreSQL output
- 5TimescaleDB optimized for time-series IoT data
- 6EMQX supports millions of concurrent connections
Individual Services(4 services)
Copy individual services to mix and match with your existing compose files.
emqx
emqx:
image: emqx/emqx:latest
container_name: emqx
restart: unless-stopped
ports:
- "1883:1883"
- "8083:8083"
- "8084:8084"
- ${EMQX_DASHBOARD:-18083}:18083
environment:
- EMQX_NAME=emqx
- EMQX_HOST=127.0.0.1
volumes:
- emqx_data:/opt/emqx/data
- emqx_log:/opt/emqx/log
timescaledb
timescaledb:
image: timescale/timescaledb:latest-pg15
container_name: timescaledb
restart: unless-stopped
ports:
- ${TIMESCALE_PORT:-5432}:5432
environment:
- POSTGRES_USER=${DB_USER}
- POSTGRES_PASSWORD=${DB_PASSWORD}
- POSTGRES_DB=iot
volumes:
- timescaledb_data:/var/lib/postgresql/data
telegraf
telegraf:
image: telegraf:latest
container_name: telegraf
restart: unless-stopped
volumes:
- ./telegraf/telegraf.conf:/etc/telegraf/telegraf.conf:ro
depends_on:
- emqx
- timescaledb
grafana
grafana:
image: grafana/grafana:latest
container_name: iot-grafana
restart: unless-stopped
ports:
- ${GRAFANA_PORT:-3000}:3000
environment:
- GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_PASSWORD:-admin}
volumes:
- grafana_data:/var/lib/grafana
depends_on:
- timescaledb
Quick Start
terminal
1# 1. Create the compose file2cat > docker-compose.yml << 'EOF'3services:4 emqx:5 image: emqx/emqx:latest6 container_name: emqx7 restart: unless-stopped8 ports:9 - "1883:1883"10 - "8083:8083"11 - "8084:8084"12 - "${EMQX_DASHBOARD:-18083}:18083"13 environment:14 - EMQX_NAME=emqx15 - EMQX_HOST=127.0.0.116 volumes:17 - emqx_data:/opt/emqx/data18 - emqx_log:/opt/emqx/log1920 timescaledb:21 image: timescale/timescaledb:latest-pg1522 container_name: timescaledb23 restart: unless-stopped24 ports:25 - "${TIMESCALE_PORT:-5432}:5432"26 environment:27 - POSTGRES_USER=${DB_USER}28 - POSTGRES_PASSWORD=${DB_PASSWORD}29 - POSTGRES_DB=iot30 volumes:31 - timescaledb_data:/var/lib/postgresql/data3233 telegraf:34 image: telegraf:latest35 container_name: telegraf36 restart: unless-stopped37 volumes:38 - ./telegraf/telegraf.conf:/etc/telegraf/telegraf.conf:ro39 depends_on:40 - emqx41 - timescaledb4243 grafana:44 image: grafana/grafana:latest45 container_name: iot-grafana46 restart: unless-stopped47 ports:48 - "${GRAFANA_PORT:-3000}:3000"49 environment:50 - GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_PASSWORD:-admin}51 volumes:52 - grafana_data:/var/lib/grafana53 depends_on:54 - timescaledb5556volumes:57 emqx_data:58 emqx_log:59 timescaledb_data:60 grafana_data:61EOF6263# 2. Create the .env file64cat > .env << 'EOF'65# IoT Sensor Platform66EMQX_DASHBOARD=1808367TIMESCALE_PORT=543268GRAFANA_PORT=30006970# Database71DB_USER=iot72DB_PASSWORD=iot_password7374# Grafana75GRAFANA_PASSWORD=admin76EOF7778# 3. Start the services79docker compose up -d8081# 4. View logs82docker compose logs -fOne-Liner
Run this command to download and set up the recipe in one step:
terminal
1curl -fsSL https://docker.recipes/api/recipes/iot-sensor-platform/run | bashTroubleshooting
- EMQX connection refused on port 1883: Check if EMQX container started properly and verify firewall rules allow MQTT traffic
- Telegraf failing to connect to EMQX: Ensure MQTT input plugin configuration uses correct broker URL 'emqx:1883' for container networking
- TimescaleDB connection errors from Grafana: Verify PostgreSQL service is running and use 'timescaledb:5432' as data source URL
- High memory usage in TimescaleDB: Enable TimescaleDB compression on older chunks and configure appropriate retention policies for sensor data
- EMQX dashboard shows authentication failures: Default credentials are admin/public, check client certificates if using SSL/TLS connections
- Missing data in Grafana dashboards: Verify Telegraf is successfully writing to TimescaleDB by checking PostgreSQL logs and table row counts
Community Notes
Loading...
Loading notes...
Download Recipe Kit
Get all files in a ready-to-deploy package
Includes docker-compose.yml, .env template, README, and license
Components
emqxtimescaledbtelegrafgrafana
Tags
#iot#mqtt#emqx#timescaledb#telegraf#sensors#grafana
Category
Home Lab & Self-HostingAd Space
Shortcuts: C CopyF FavoriteD Download