IoT stack is a set of services, useful for internet of things projects. It combines several components that allows organization of communication, logging and monitoring of different sensors.

In this blog post, I’ll guide you through the process of installing IoT stack on a Raspberry Pi using Portainer.

Before we get started, here’s a brief overview of each service:

  • Mosquitto - An open-source MQTT broker that allows devices to communicate with each other via a publish/subscribe model
  • InfluxDB2 - A time-series database that is optimized for storing and querying time-stamped data
  • Telegraf - A plugin-driven agent that collects, processes, and aggregates data from IoT devices
  • Grafana - A data visualization tool that allows you to create and share dashboards and graphs

Now, let’s get started with the installation process!

Prerequisites Link to heading

  • Raspberry Pi 4 setup and updated
  • Portainer installed
  • Nginx Proxy Manager service installed

Step 0 - Define local mount folders Link to heading

Service will use local folders, mounted to docker container, to store its data.

For service we will need to create folder:

  • /ssd/iot/influxdb2/config
  • /ssd/iot/influxdb2/data
  • /ssd/iot/mosquitto/config
  • /ssd/iot/mosquitto/log
  • /ssd/iot/mosquitto/data
  • /ssd/iot/grafana
  • /ssd/iot/telegraf
mkdir -p /ssd/iot/influxdb2/config
mkdir -p /ssd/iot/influxdb2/data
mkdir -p /ssd/iot/mosquitto/config
mkdir -p /ssd/iot/mosquitto/log
mkdir -p /ssd/iot/mosquitto/data
mkdir -p /ssd/iot/grafana
mkdir -p /ssd/iot/telegraf

Step 1 - Install IoT stack Link to heading

With Portainer installed, it is possible to start new stack. To do this, follow these steps:

  • Open Portainer in your web browser and navigate to the “Stacks” page
  • Click the “Add stack” button
  • Enter a name for the stack (e.g., “iot-stack”) and paste the following code into the “Web editor” section:
version: '3'

networks:
  intranet:
    external: true

services:
      
  recorder:
    image: influxdb:latest
    restart: unless-stopped
    ports:
      - "8086:8086"
    networks:
      intranet:
        aliases:
          - recorder
    volumes:
      - /ssd/iot/influxdb2/data:/var/lib/influxdb2
      - /ssd/iot/influxdb2/config:/etc/influxdb2
    environment:
      - DOCKER_INFLUXDB_INIT_MODE=setup
      - DOCKER_INFLUXDB_INIT_USERNAME=admin
      - DOCKER_INFLUXDB_INIT_PASSWORD=superpwd
      - DOCKER_INFLUXDB_INIT_ORG=homelab
      - DOCKER_INFLUXDB_INIT_BUCKET=mybucket

  mqtt:
    image: eclipse-mosquitto:2.0.15
    restart: unless-stopped
    volumes:
      - /ssd/iot/mosquitto/config:/mosquitto/config
      - /ssd/iot/mosquitto/data:/mosquitto/data
      - /ssd/iot/mosquitto/log:/mosquitto/log
    ports:
      - "1883:1883"
      - "1884:1884"
    networks:
      intranet:
        aliases:
          - mqtt
    environment:
      - TZ=Europe/Madrid

  telegraf:
    image: telegraf:latest
    restart: unless-stopped
    ports:
      - "8092:8092"
      - "8094:8094"
      - "8125:8125"
      - "25826:25826"
    networks:
      intranet:
        aliases:
          - telegraf
    volumes:
      # System
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - /sys:/host/sys:ro
      - /proc:/host/proc:ro
      - /etc:/host/etc:ro
      # Data storages
      - /ssd/iot/telegraf/telegraf.conf:/etc/telegraf/telegraf.conf
    environment:
      - HOST_PROC=/host/proc
      - HOST_SYS=/host/sys
      - HOST_ETC=/host/etc
          
  grafana:
    image: grafana/grafana:latest
    restart: always
    volumes:
      - /ssd/iot/grafana:/var/lib/grafana:rw
    ports:
      - "3100:3000"
    networks:
      intranet:
        aliases:
          - grafana
    environment:
      - GF_AUTH_DISABLE_LOGIN_FORM=true
      - GF_AUTH_ANONYMOUS_ENABLED=true
      - GF_AUTH_ANONYMOUS_ORG_ROLE=Admin
      - GF_SECURITY_ALLOW_EMBEDDING=true

Step 2 - Configure IoT-stack services Link to heading

Two services requires configuration passed via config files.

Mosquitto Link to heading

Create a text file under /ssd/iot/mosquitto/config/mosquitto.conf with content:

persistence true
persistence_location /mosquitto/data/
log_dest file /mosquitto/log/mosquitto.log
listener 1883

## Authentication ##
allow_anonymous false
password_file /mosquitto/config/password.txt

This config will define location for persistence storage and log output. Also authentication will be configured to take username/password pairs from password.txt file, located in the same folder.

Additional Mosquitto configurations can be found on mosquitto.conf man page

Telegraf Link to heading

Telegraf has a rather large configuration file. For starting, it is possible to create empty file /ssd/iot/telegraf/telegraf.conf

Information on configuration values can be found on Configuring Telegraf

Step 3 - Configure Proxy Link to heading

Add proxied hosts for:

  • Mosquitto
    • DNS name: mqtt.home
    • Forwarded hostname: mqtt
    • Forwarded port: 1883
  • Influxdb
    • DNS name: recorder.home
    • Forwarded hostname: recorder
    • Forwarded port: 8086
  • Grafana
    • DNS name: grafana.home
    • Forwarded hostname: grafana
    • Forwarded port: 3100

TO BE CONTINUED… Link to heading

And that’s it! You now have iot stack running on your homelab. Now you can proceed with connecting IoT devices, logging and monitoring them.

In the following post Homelab. HomeAssistant, I will describe how to install HomeAssistant - a popular open-source home automation platform that allows you to control and monitor devices in your home from a single interface.