diff --git a/emqx/Dockerfile b/emqx/Dockerfile new file mode 100644 index 0000000..a44ccc8 --- /dev/null +++ b/emqx/Dockerfile @@ -0,0 +1,15 @@ +# EMQX для IoT на платформе Nubes (контейнер «Простой HTTP»). +# Образ: naeel/iot-emqx (Docker Hub, публичный). +# Единственный экспонируемый порт — 8083 (MQTT over WebSocket). +# Auth/ACL URL монолита задаются env (см. HISTORY раздел 16). + +FROM emqx/emqx:5.5.1 + +COPY emqx.conf /opt/emqx/etc/emqx.conf + +# Заглушки auth/ACL URL — реальный адрес монолита задаётся env в deck-UI +# или kubectl set env после создания обоих контейнеров. +ENV EMQX_AUTHENTICATION__1__URL=http://iot-service:9090/internal/mqtt/auth \ + EMQX_AUTHORIZATION__SOURCES__1__URL=http://iot-service:9090/internal/mqtt/acl + +EXPOSE 8083 18083 diff --git a/emqx/Makefile b/emqx/Makefile new file mode 100644 index 0000000..e029ec7 --- /dev/null +++ b/emqx/Makefile @@ -0,0 +1,13 @@ +# EMQX-контейнер для IoT (образ naeel/iot-emqx). + +VERSION ?= v0.1.0 +IMAGE ?= naeel/iot-emqx + +.PHONY: docker-build docker-push + +docker-build: + docker build -t $(IMAGE):$(VERSION) -t $(IMAGE):latest . + +docker-push: + docker push $(IMAGE):$(VERSION) + docker push $(IMAGE):latest diff --git a/emqx/emqx.conf b/emqx/emqx.conf new file mode 100644 index 0000000..55dc94e --- /dev/null +++ b/emqx/emqx.conf @@ -0,0 +1,90 @@ +## EMQX 5.x — конфиг для контейнера IoT на платформе Nubes. +## Вшит в образ naeel/iot-emqx. Auth/ACL URL переопределяются env-переменными +## (EMQX_AUTHENTICATION__1__URL, EMQX_AUTHORIZATION__SOURCES__1__URL) в deck-UI +## или kubectl set env — адрес монолита становится известен после его создания. + +node { + name = "emqx@127.0.0.1" + cookie = "iot-emqx-cookie-mvp" + data_dir = "/opt/emqx/data" +} + +## HTTP Auth — монолит проверяет устройства в PostgreSQL (iot_devices). +authentication = [ + { + mechanism = password_based + backend = http + enable = true + method = post + url = "http://iot-service:9090/internal/mqtt/auth" + body { + username = "${username}" + password = "${password}" + clientid = "${clientid}" + } + headers { + "content-type" = "application/json" + } + connect_timeout = 5s + request_timeout = 5s + pool_size = 8 + } +] + +## ACL — монолит разрешает pub/sub по топикам устройств. +## no_match = deny: недоступность backend = запрет. +authorization { + no_match = deny + deny_action = disconnect + cache { + enable = true + max_size = 32 + ttl = 1m + } + sources = [ + { + type = http + enable = true + method = post + url = "http://iot-service:9090/internal/mqtt/acl" + body { + username = "${username}" + clientid = "${clientid}" + action = "${action}" + topic = "${topic}" + } + headers { + "content-type" = "application/json" + } + connect_timeout = 5s + request_timeout = 5s + pool_size = 8 + } + ] +} + +mqtt { + max_packet_size = 1MB + max_topic_levels = 10 + retain_available = false +} + +## Listeners: WebSocket — единственный порт контейнера платформы (8083). +## TCP 1883 остаётся для диагностики (не экспонируется платформой). +listeners.tcp.default { + bind = "0.0.0.0:1883" + max_connections = 1024 +} + +listeners.ws.default { + bind = "0.0.0.0:8083" + mqtt_path = "/mqtt" + max_connections = 512 +} + +## Dashboard — для диагностики через port-forward (наружу не экспонируется). +dashboard { + listeners.http { + bind = 18083 + } +}