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:
- Broker.
mosquitto_sub -h broker.connectmq.com -p 1883 -i check-a1b2c3 -t "connectmq/demo/a1b2c3/#" -vkomutunu çalıştırın. Hiçbir şey görünmüyorsa sorun stack'te değil, yayıncıdadır. - 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. - 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. - 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. - 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.



