IoT Eğitimleri

MQTT Verisi için Docker Compose ile TIG Stack

Bir MQTT broker'a abone olan, sensör verisini saklayan ve hazır yapılandırılmış veri kaynağı ile dashboard'la açılan eksiksiz bir Telegraf, InfluxDB 2 ve Grafana docker-compose kurulumu; ayrıca ilk çalıştırmayı bozan tuzaklar.

Telegraf'ın MQTT topic'lerini okuduğu, InfluxDB'nin metrikleri sakladığı ve Grafana'nın dashboard gösterdiği TIG stack Docker Compose diyagramı
Bunu kendi MQTT broker’ınızda çalıştırınFree planla özel, yönetilen bir MQTT broker alın ve hazır kod örnekleriyle başlayın.
Ücretsiz deneyin Kod örnekleri Kart gerekmez

Docker Compose ile kurulan bir TIG stack, tek bir makinede eksiksiz bir MQTT veri hattı sunar: Telegraf broker'ınıza abone olur, InfluxDB okumaları saklar ve Grafana bunları grafiğe döker. Bu rehberde gereken tüm dosyaları oluşturacak, stack'i tek komutla başlatacak ve Grafana'yı önceden hazırlanmış, canlı veri gösteren bir dashboard ile açacaksınız.

Ne İnşa Edeceksiniz

Stack üç container ve bir dış bağımlılıktan, yani MQTT broker'dan oluşur:

devices / simulator --> MQTT broker (broker.connectmq.com)
                              |
                         Telegraf (mqtt_consumer)
                              |
                         InfluxDB 2 (bucket "sensors")
                              |
                         Grafana (provisioned data source + dashboard)

Broker bilinçli olarak Compose'un dışında tutulur. Broker'lar, birçok tüketicinin paylaştığı uzun ömürlü altyapılardır; TIG stack bu tüketicilerden yalnızca biridir. Telegraf broker'a sıradan bir MQTT istemcisi olarak bağlanır; bu, public test broker için de özel bir broker için de aynı şekilde çalışır.

TIG Stack için Neden Docker Compose

Üç aracın her biri doğrudan sisteme kurulabilir, ancak bu üç paket deposu, üç servis tanımı ve sisteme dağılmış yapılandırma dosyaları demektir. Compose tüm veri hattını sürümleyebileceğiniz, başka bir makineye kopyalayabileceğiniz ya da iz bırakmadan kaldırabileceğiniz tek bir klasörde toplar. Ayrıca sürümleri açıkça sabitler; böylece bir işletim sistemi güncellemesi InfluxDB'yi veya Grafana'yı habersizce yükseltmez.

Bunun bedeli, Compose'un tek sunuculu bir araç olmasıdır. Bir geliştirme dizüstü bilgisayarı, bir laboratuvar, küçük bir saha gateway'i ya da tek bir tesisten veri toplayan şirket içi bir sunucu için uygundur. Yüksek erişilebilirlik sağlamaz; sunucu çökerse stack de çöker. Birçok izleme senaryosunda bu kabul edilebilir, çünkü cihazlar broker'a yayın yapmaya devam eder ve Telegraf geri geldiğinde kaldığı yerden devam eder; Telegraf'ı persistent_session = true ile QoS 1'e geçirirseniz broker kısa bir kesinti sırasında mesajlarını tutabilir.

Proje Yapısı

Bu dizin yapısını oluşturun:

tig-mqtt/
  .env
  docker-compose.yml
  telegraf/
    telegraf.conf
  grafana/
    provisioning/
      datasources/
        influxdb.yml
      dashboards/
        dashboards.yml
    dashboards/
      mqtt-sensors.json

Toplam altı dosya. Her biri aşağıda eksiksiz olarak gösteriliyor.

Adım 1: Ortam Değişkenleri

Gizli bilgiler ve adlar, Docker Compose'un otomatik olarak okuduğu .env dosyasında durur. Bu dosyayı sürüm kontrolünün dışında tutun.

# .env
INFLUX_USERNAME=admin
INFLUX_PASSWORD=change-me-please
INFLUX_ORG=iot
INFLUX_BUCKET=sensors
INFLUX_TOKEN=replace-with-a-long-random-token
GRAFANA_PASSWORD=change-me-too

MQTT_SERVER=tcp://broker.connectmq.com:1883
MQTT_TOPIC_PREFIX=connectmq/demo/a1b2c3
MQTT_CLIENT_ID=telegraf-a1b2c3
MQTT_USERNAME=
MQTT_PASSWORD=

Gerçek bir token'ı openssl rand -hex 32 ile üretin. Public broker üzerinde topic'lerinizin ayrı kalması için a1b2c3 değerini kendi rastgele dizenizle değiştirin.

Adım 2: TIG Stack Docker Compose Dosyası

# docker-compose.yml
services:
  influxdb:
    image: influxdb:2.7
    restart: unless-stopped
    ports:
      - "8086:8086"
    environment:
      DOCKER_INFLUXDB_INIT_MODE: setup
      DOCKER_INFLUXDB_INIT_USERNAME: ${INFLUX_USERNAME}
      DOCKER_INFLUXDB_INIT_PASSWORD: ${INFLUX_PASSWORD}
      DOCKER_INFLUXDB_INIT_ORG: ${INFLUX_ORG}
      DOCKER_INFLUXDB_INIT_BUCKET: ${INFLUX_BUCKET}
      DOCKER_INFLUXDB_INIT_RETENTION: 30d
      DOCKER_INFLUXDB_INIT_ADMIN_TOKEN: ${INFLUX_TOKEN}
    volumes:
      - influxdb-data:/var/lib/influxdb2
      - influxdb-config:/etc/influxdb2
    healthcheck:
      test: ["CMD", "influx", "ping"]
      interval: 10s
      timeout: 5s
      retries: 12

  telegraf:
    image: telegraf:1.32
    restart: unless-stopped
    depends_on:
      influxdb:
        condition: service_healthy
    environment:
      INFLUX_TOKEN: ${INFLUX_TOKEN}
      INFLUX_ORG: ${INFLUX_ORG}
      INFLUX_BUCKET: ${INFLUX_BUCKET}
      MQTT_SERVER: ${MQTT_SERVER}
      MQTT_TOPIC_PREFIX: ${MQTT_TOPIC_PREFIX}
      MQTT_CLIENT_ID: ${MQTT_CLIENT_ID}
      MQTT_USERNAME: ${MQTT_USERNAME}
      MQTT_PASSWORD: ${MQTT_PASSWORD}
    volumes:
      - ./telegraf/telegraf.conf:/etc/telegraf/telegraf.conf:ro

  grafana:
    image: grafana/grafana:11.3.0
    restart: unless-stopped
    depends_on:
      - influxdb
    ports:
      - "3000:3000"
    environment:
      GF_SECURITY_ADMIN_PASSWORD: ${GRAFANA_PASSWORD}
      INFLUX_TOKEN: ${INFLUX_TOKEN}
      INFLUX_ORG: ${INFLUX_ORG}
      INFLUX_BUCKET: ${INFLUX_BUCKET}
    volumes:
      - grafana-data:/var/lib/grafana
      - ./grafana/provisioning:/etc/grafana/provisioning:ro
      - ./grafana/dashboards:/var/lib/grafana/dashboards:ro

volumes:
  influxdb-data:
  influxdb-config:
  grafana-data:

Health check önemlidir. O olmadan Telegraf, InfluxDB ilk çalıştırma kurulumunu bitirmeden başlayabilir, ilk yazmalarında başarısız olur ve logları hatalarla doldurur. condition: service_healthy, Compose'un influx ping başarılı olana kadar beklemesini sağlar.

Adım 3: Telegraf Yapılandırması

Telegraf, ${VAR} referanslarını kendi ortam değişkenlerinden doldurur; bu nedenle yapılandırma dosyası hiçbir gizli bilgi içermez.

# telegraf/telegraf.conf
[agent]
  interval = "10s"
  flush_interval = "10s"
  omit_hostname = true

[[inputs.mqtt_consumer]]
  servers = ["${MQTT_SERVER}"]
  topics = ["${MQTT_TOPIC_PREFIX}/+/+/telemetry"]
  qos = 0
  client_id = "${MQTT_CLIENT_ID}"
  username = "${MQTT_USERNAME}"
  password = "${MQTT_PASSWORD}"

  name_override = "sensor"
  topic_tag = ""
  data_format = "json"
  tag_keys = ["device"]
  json_time_key = "ts"
  json_time_format = "unix_ms"

  [[inputs.mqtt_consumer.topic_parsing]]
    topic = "${MQTT_TOPIC_PREFIX}/+/+/telemetry"
    tags = "_/_/_/line/_/_"

[[outputs.influxdb_v2]]
  urls = ["http://influxdb:8086"]
  token = "${INFLUX_TOKEN}"
  organization = "${INFLUX_ORG}"
  bucket = "${INFLUX_BUCKET}"

http://influxdb:8086 URL'sine dikkat edin: Compose ağı içinde container'lar birbirine localhost ile değil, servis adıyla ulaşır. tags deseni connectmq/demo/a1b2c3 gibi üç seviyeli bir önek varsayar; önekinizin derinliği farklıysa baştaki alt çizgi sayısını ayarlayın. Bu seçeneklerin satır satır açıklaması için Telegraf MQTT consumer rehberine bakın.

Adım 4: Grafana Veri Kaynağını Hazırlayın

Provisioning, InfluxDB veri kaynağını başlangıçta oluşturur; böylece kimsenin arayüzde tıklayarak ilerlemesi gerekmez. Grafana, provisioning dosyalarındaki ortam değişkenlerini de genişletir.

# grafana/provisioning/datasources/influxdb.yml
apiVersion: 1
datasources:
  - name: InfluxDB
    uid: influxdb
    type: influxdb
    access: proxy
    url: http://influxdb:8086
    isDefault: true
    jsonData:
      version: Flux
      organization: ${INFLUX_ORG}
      defaultBucket: ${INFLUX_BUCKET}
    secureJsonData:
      token: ${INFLUX_TOKEN}

Sabit uid, dashboard'un bu veri kaynağına güvenilir şekilde başvurmasını sağlar.

Adım 5: Hazır Bir Dashboard Ekleyin

Önce Grafana'ya dashboard'ların nerede durduğunu söyleyin:

# grafana/provisioning/dashboards/dashboards.yml
apiVersion: 1
providers:
  - name: mqtt
    folder: MQTT
    type: file
    options:
      path: /var/lib/grafana/dashboards

Ardından dashboard'un kendisini ekleyin. Cihaz başına bir sıcaklık zaman serisi ve veri gönderen cihaz sayısını gösteren bir stat paneli içerir.

{
  "uid": "mqtt-sensors",
  "title": "MQTT Sensors",
  "schemaVersion": 39,
  "refresh": "10s",
  "time": { "from": "now-1h", "to": "now" },
  "panels": [
    {
      "id": 1,
      "type": "timeseries",
      "title": "Temperature by device",
      "gridPos": { "x": 0, "y": 0, "w": 18, "h": 10 },
      "datasource": { "type": "influxdb", "uid": "influxdb" },
      "fieldConfig": { "defaults": { "unit": "celsius" }, "overrides": [] },
      "targets": [
        {
          "refId": "A",
          "query": "from(bucket: \"sensors\")\n  |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n  |> filter(fn: (r) => r._measurement == \"sensor\" and r._field == \"temperature\")\n  |> group(columns: [\"device\"])\n  |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)"
        }
      ]
    },
    {
      "id": 2,
      "type": "stat",
      "title": "Reporting devices (last 5 min)",
      "gridPos": { "x": 18, "y": 0, "w": 6, "h": 10 },
      "datasource": { "type": "influxdb", "uid": "influxdb" },
      "targets": [
        {
          "refId": "A",
          "query": "from(bucket: \"sensors\")\n  |> range(start: -5m)\n  |> filter(fn: (r) => r._measurement == \"sensor\" and r._field == \"temperature\")\n  |> group()\n  |> distinct(column: \"device\")\n  |> count()"
        }
      ]
    }
  ]
}

.env içinde bucket adını değiştirdiyseniz iki sorgudaki "sensors" değerini de değiştirin. Bu JSON'u mevcut herhangi bir Grafana örneğinde Dashboards, ardından New, ardından Import yoluyla da içe aktarabilirsiniz.

Adım 6: Stack'i Başlatın ve Veri Gönderin

cd tig-mqtt
docker compose up -d
docker compose ps
docker compose logs -f telegraf

Şimdi veri yayınlayın. En hızlı sürekli kaynak Python MQTT cihaz simülatörümüzdür; MQTT_TOPIC_PREFIX ile eşleşmesi için --prefix connectmq/demo/a1b2c3 ile çalıştırın. Tek bir test mesajı da işe yarar:

mosquitto_pub -h broker.connectmq.com -p 1883 -i pub-a1b2c3 \
  -t connectmq/demo/a1b2c3/line1/sensor-0001/telemetry \
  -m "{\"device\":\"sensor-0001\",\"ts\":$(date +%s%3N),\"temperature\":22.4,\"humidity\":41.0}"

http://localhost:3000 adresini açın, GRAFANA_PASSWORD ile admin olarak giriş yapın ve MQTT klasöründeki MQTT Sensors dashboard'unu açın.

Her Katmanı Sırayla Doğrulayın

Dashboard boş kaldığında aynı anda birkaç şeyi değiştirme dürtüsüne direnin. Veri hattı boyunca aşağı doğru ilerleyin ve bir sonrakine geçmeden önce her katmanı doğrulayın:

  1. Broker. mosquitto_sub -h broker.connectmq.com -p 1883 -i check-a1b2c3 -t "connectmq/demo/a1b2c3/#" -v komutunu çalıştırın. Hiçbir şey görünmüyorsa sorun stack'te değil, yayıncıdadır.
  2. Telegraf bağlantısı. docker compose logs telegraf çıktısı, eklentinin hatasız bağlandığını göstermelidir. Kimlik doğrulama hataları ve topic ayrıştırma hataları burada görünür.
  3. Telegraf ayrıştırması. Geçici olarak files = ["stdout"] içeren bir [[outputs.file]] bloğu ekleyin ve Telegraf'ı yeniden başlatın. Ayrıştırılan metrikler loglarda line protocol olarak görünür; bu da JSON ve topic eşlemesinin doğru olduğunu kanıtlar.
  4. InfluxDB. docker compose exec influxdb influx query 'from(bucket: "sensors") |> range(start: -5m) |> limit(n: 3)' komutunu çalıştırın. Container içindeki CLI, init kurulumu tarafından zaten yapılandırılmıştır.
  5. Grafana. Veri kaynağı sayfasını açın ve Save and test'e tıklayın; ardından dashboard'un zaman aralığının verinin yazıldığı dönemi kapsadığını kontrol edin.

Pratikte sorunların çoğu 1. ya da 3. adımda bulunur: tek bir karakter farklı olan bir topic öneki ya da yapılandırmanın beklediği JSON olmayan bir payload.

İlk Çalıştırma Tuzakları

Sorun Neden Çözüm
.env içindeki token reddediliyor InfluxDB init değişkenleri yalnızca boş bir volume'e uygulanır Sıfırlamak için docker compose down -v ya da arayüzde yeni bir token oluşturun
Telegraf: localhost:8086 bağlantısı reddedildi Container içinde yanlış hostname http://influxdb:8086 kullanın
Dashboard "No data" gösteriyor .env içindeki topic öneki yayınlanandan farklı mosquitto_sub -t "connectmq/demo/a1b2c3/#" -v ile karşılaştırın
Telegraf: topic ayrıştırma hatası Önek derinliği değişmiş ama tags deseni değişmemiş _ segment sayısını topic seviyelerine eşleyin
Grafana veri kaynağı hatası Token ya da org uyuşmazlığı Veri kaynağı sayfasını kontrol edin; değerler .env dosyasından gelir
Stack çalışıyor ama veri down -v sonrası kayboluyor Volume'ler silinmiş -v olmadan docker compose down kullanın

Özel Bir Broker'a Geçiş

Gerçek ekipman için yalnızca .env değişir. Stack'i ConnectMQ gibi tamamen yönetilen bir MQTT hizmetine yönlendirin:

MQTT_SERVER=ssl://broker.connectmq.com:8883
MQTT_TOPIC_PREFIX=connectmq/factory1/production
MQTT_CLIENT_ID=YOUR_CLIENT_ID
MQTT_USERNAME=YOUR_USERNAME
MQTT_PASSWORD=YOUR_PASSWORD

Sertifika Let's Encrypt tarafından verilir; bu nedenle Telegraf ek TLS ayarı gerekmeden ona güvenir. Telegraf container'ını yeni değerlerle yeniden oluşturmak için docker compose up -d komutunu tekrar çalıştırın. Ayrıca Grafana'yı makinenizin dışına açmadan önce HTTPS'li bir reverse proxy arkasına alın ve influxdb-data volume'ünü yedekleyin.

Dashboard hazır olduğunda aynı sorgular üzerine IoT sensör verisi için Grafana alarmları ekleyin. Cihaz tarafındaki daha geniş istemci seçenekleri için MQTT istemci kütüphaneleri rehberine bakın; health check'ler ve ortam dosyaları ise Docker Compose dokümantasyonunda ayrıntılı olarak anlatılır.

ConnectMQ ile Başlayın

Stack'i bugün simüle edilmiş veriyle ayağa kaldırmak için public MQTT test broker'ını kullanın. Üretim için ConnectMQ, TLS, MQTT 5 ve topic'leri Telegraf görmeden önce canlı izleyebileceğiniz bir portal içeren, tamamen yönetilen bir MQTT broker çalıştırır. app.connectmq.com adresinde kredi kartı gerektirmeden ücretsiz bir Serverless broker oluşturun, ardından kimlik bilgilerini .env dosyasına yapıştırın. Barındırma seçeneklerini değerlendiriyorsanız bulut MQTT broker rehberimizi okuyun.

Sık Sorulan Sorular

MQTT broker'ı aynı Docker Compose dosyası içinde çalıştırabilir miyim?

Çalıştırabilirsiniz, ancak paylaşılan, yönetilen bir broker'ı işletmek genellikle daha basittir ve diğer tüketicilerin aynı veriyi kullanmasına olanak tanır. Broker'ı Compose dışında tutmak, stack'i yeniden başlatmanın cihazlarınızı asla kesintiye uğratmaması anlamına da gelir.

Bu TIG stack Docker Compose kurulumu InfluxDB 3 ile çalışır mı?

Değiştirilmeden çalışmaz. InfluxDB 3 farklı bir imaj, kurulum prosedürü ve sorgu dilleri kullanır; bu nedenle buradaki init değişkenleri ve Flux sorguları InfluxDB 2.7 için geçerlidir.

Daha fazla dashboard nasıl eklerim?

Ek dashboard JSON dosyalarını grafana/dashboards klasörüne bırakın. Grafana bunları dosya sağlayıcısı aracılığıyla otomatik olarak alır.

Veri ne kadar disk alanı kullanır?

Seri sayısına ve mesaj hızına bağlıdır. Bucket'ın 30 günlük saklama süresi büyümeyi sınırlı tutar; disk dar ise bu süreyi kısaltın ya da eski veriyi downsample edin.

İlgili yazılar

Test, Betik ve Hata Ayıklama için En İyi MQTT CLI Araçları

mosquitto_pub/sub, MQTTX CLI, HiveMQ MQTT CLI, MQTT.js CLI, curl ve mqttui'nin uygulamalı karşılaştırması; betik yazma ve hata ayıklama için doğru aracı seçebilmeniz için aynı test broker.connectmq.com üzerinde çalıştırıldı.

7 dk okuma

Tüm yazılar →

Özel MQTT broker’ınız birkaç tık uzağınızda

Hesabınızı oluşturun, broker kimlik bilgilerinizi alın ve ilk cihazınızı bağlayın — kurulacak, yamalanacak ya da ölçeklendirilecek sunucu yok.