Es gibt eine Vielzahl von verschiedenen Brokern, die alle ihre Vor- und Nachteile haben. Ich habe mich hier für VerneMQ bzw. Mosquitto entschieden.
Mosquitto gibt es in der offiziellen Docker-Bibliothek als eclipse-mosquitto. Demnach schaut die Compose-Datei wie folgt erstmal aus.
/opt/docker/services/mqtt/docker-compose.yml:
version: '3'
services:
broker:
image: eclipse-mosquitto:2
container_name: MQTT
hostname: mqtt.example.com
restart: unless-stopped
network_mode: bridge
ports:
- 127.0.0.1:18830:18830
- 127.0.0.1:8080:8080
environment:
TZ: Europe/Berlin
volumes:
- /opt/docker/services/mqtt/volumes:/mosquitto
tty: true
stdin_open: true
Im Verzeichnis /opt/docker/sevices/mqtt/volumes/config sollte wenigstens die Datei mosquitto.conf liegen:
allow_anonymous false
allow_zero_length_clientid false
# 256 MB of RAM allowed
memory_limit 268435456
persistent_client_expiration 1w
# Time in seconds between updates of the $SYS tree.
# Set to 0 to disable the publishing of the $SYS tree.
sys_interval 15
listener 18830
listener 8080
protocol websockets
password_file /mosquitto/config/passwd.txt
# acl_file /mosquitto/config/acl.txt
persistence false
persistence_file mosquitto.db
persistence_location /mosquitto/data/
log_dest stdout
#log_type error
#log_type warning
connection_messages true
log_timestamp true
Da in der Konfiguration auch eine Passwortdatei angegeben ist, erzeugen wir die Zugänge über einen Direktaufruf im Docker-Image:
# touch /opt/docker/services/mqtt/volumes/config/passwd.txt
# docker run --rm -it -v /opt/docker/services/mqtt/volumes/config/passwd.txt:/passwd.txt eclipse-mosquitto mosquitto_passwd /passwd.txt <username>
Die Passwörter werden dann interaktiv abgefragt.
Möchte man noch Zugriffsrechte auf Topics einstellen, kann dies über acl_file /mosquitto/config/acl.txt aktiviert werden: Anleitung.
Für VerneMQ gibt es ein offizielles Image vernemq/vernemq im Docker-Hub. Auf Grund dessen, dass noch die Benutzerverwaltung komfortabel per Web-Oberfläche gemacht werden soll, wird hier auf eine eigene Kreation zurückgegriffen andreasmueller/vernemq:amd64.
Da hier explizit eine Datei (control.ini) in den Container gemounted wird, muss diese vor dem ersten Start existieren.
/opt/docker/services/mqtt/docker-compose.yml:
version: '3'
services:
broker:
image: andreasmueller/vernemq:amd64
container_name: MQTT
hostname: mqtt.example.com
restart: unless-stopped
network_mode: bridge
ports:
- 127.0.0.1:5000:5000
- 127.0.0.1:8080:8080
- 127.0.0.1:18830:18830
environment:
TZ: Europe/Berlin
volumes:
- /opt/docker/services/mqtt/volumes/control.ini:/etc/vernemq/control.ini:ro
- /opt/docker/services/mqtt/volumes/data:/var/lib/control
Die Datei in Stichpunkten:
andreasmueller/vernemq:amd64: Sourcecontrol.ini vom original abweichend: Address = 0.0.0.0/var/lib/controlUm den konfigurierten Broker zugänglich zu machen (derzeit ja nur für localhost verfügbar), nutzen wir wieder die Vorzüge von NginX.
upstream mqtt-tcp {
server 127.0.0.1:18830;
}
server {
listen 1883;
listen [::]:1883;
listen 8883 ssl;
listen [::]:8883 ssl;
include /etc/nginx/snippets/ssl-stream.conf;
ssl_certificate /path/to/cert/mqtt.example.com/fullchain.pem;
ssl_certificate_key /path/to/cert/mqtt.example.com/privkey.pem;
proxy_pass mqtt-tcp;
# use the proxy protocol for VerneMQ
proxy_protocol on;
}
upstream mqtt-ws {
server 127.0.0.1:8080;
}
upstream mqtt-control {
server 127.0.0.1:5000;
}
server {
listen 80;
listen [::]:80;
server_name mqtt.example.com;
server_tokens off;
# redirect VerneMQ Control UI to HTTPS
location / {
return 301 https://$http_host$request_uri;
}
# MQTT over WebSocket (ws://mqtt.example.com/mqtt)
location = /mqtt {
# when used with Mosquitto, only set http://mqtt-ws/; (trailing mqtt removed)
proxy_pass http://mqtt-ws/mqtt;
proxy_http_version 1.1;
proxy_redirect off;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $server_name;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header X-Forwarded-Port $server_port;
}
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name mqtt.example.com;
server_tokens off;
include /etc/nginx/snippets/ssl-http.conf;
ssl_certificate /path/to/cert/mqtt.example.com/fullchain.pem;
ssl_certificate_key /path/to/cert/mqtt.example.com/privkey.pem;
# VerneMQ Control UI
location / {
proxy_pass http://mqtt-control/;
proxy_http_version 1.1;
proxy_redirect off;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $server_name;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header X-Nginx-Proxy true;
}
# MQTT over WebSocket [secured] (wss://mqtt.example.com/mqtt)
location = /mqtt {
# Use this when working with Mosquitto as MQTT broker
#proxy_pass http://mqtt-ws/;
proxy_pass http://mqtt-ws/mqtt;
proxy_http_version 1.1;
proxy_redirect off;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $server_name;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header X-Forwarded-Port $server_port;
}
}