Search code examples
dockernginxdocker-composemqttmosca

connect mqtt.js client to Mosca Broker through Nginx within Dockers (same Docker-compose)


I have:

  • 1 MongoDB
  • 2 Mqtt Mosca Brokers
  • 2 NodeJS App both with mqtt.js cient
  • 1 ngnix

Nginx loadbalance and proxy_pass both http and mqtt, respectively to the NodeJS apps and to the Mqtt Mosca Brokers,

so I have:

mqtt Sensors -> nginx -> Mqtt Mosca Brokers "flow" working properly

Browser -> nginx -> NodeJS App "flow working properly"

what I'm unable to do is to let the NodeJS app (mqtt.js Client part) connect to the Mqtt Mosca Brokers via nginx, somthing like:

NodeJS (mqtt.js Client) -> nginx -> Mqtt Mosca Broker.

the strange thing is that if I try:

NodeJS (mqtt.js Client) -> Mqtt Mosca Broker the flow works properly

I have the following configuration:

docker-compose.yml

     nginx:
      build: ./nginx
      links:
        - app1:app1
        - app2:app2
        - mqttbroker1:mqttbroker1
        - mqttbroker2:mqttbroker2
      ports:
        - "80:80"
        - "443:443"
        - "1883:18833"
    app1:
      build: ./node_app
      links:
        - mongo:mongo
        - mqttbroker1:mqttbroker1
        - mqttbroker2:mqttbroker2
      ports:
        - "3000"
      environment:
        - NODE_ENV=production
        - PORT=3000
    app2:
      build: ./node_app
      links:
        - mongo:mongo
        - mqttbroker1:mqttbroker1
        - mqttbroker2:mqttbroker2
      ports:
        - "3000"
      environment:
        - NODE_ENV=production
        - PORT=3000    
    mqttbroker1:
      build: ./node_broker
      links:
        - mongo:mongo
      ports:
        - "18831"
      environment:
        - NODE_ENV=production
    mqttbroker2:
      build: ./node_broker
      links:
        - mongo:mongo
      ports:
        - "18831"
      environment:
       - NODE_ENV=production
    mongo:
     container_name: mongo
     restart: always
     image: mongo
     volumes:
       - ./mongo/data:/data/db
     ports:
       - "27017:27017"

nginx.conf (excerpt)

    stream {
      upstream mqtt_cluster{

        server mqttbroker1:18831 max_fails=3 fail_timeout=30s;
        server mqttbroker2:18831 max_fails=3 fail_timeout=30s;
      }

      server {
        listen 18833; #mqtt continer prot mapped on std port (1883:18833)
        proxy_pass mqtt_cluster;
      }
}

basically if within the NodeJS Apps I use:

const mqttClient = mqtt.connect('mqtt://mqttbroker1:18831', { clientId: clientId });

it works, but if I try:

const mqttClient = mqtt.connect('mqtt://nginx:18833', { clientId: clientId });

nothing works, can anyone help?


Solution

  • I found a solution using docker-compose.yml

    instead of link I used depends_on and networks

    the YML file is:

    version: '3'
    services:
      nginx:
        build: ./nginx
        depends_on:
          - app1
          - app2
          - mqttbroker1
          - mqttbroker2
        ports:
          - "80:80"
          - "443:443"
          - "1883:1883"
        networks:
          main:
            aliases:
              - proxy
      app1:
        build: ./node_app
        depends_on:
          - mongo
          - mqttbroker1
          - mqttbroker2
        ports:
          - "3000"
        environment:
          - NODE_ENV=production
          - PORT=3000
        networks:
          main:
            aliases:
              - app1
      app2:
        build: ./node_app
        depends_on:
          - mongo
          - mqttbroker1
          - mqttbroker2
        ports:
          - "3000"
        environment:
          - NODE_ENV=production
          - PORT=3000
        networks:
          main:
            aliases:
              - app2
      mqttbroker1:
        build: ./node_broker
        depends_on:
          - mongo
        ports:
          - "18831"
        environment:
          - NODE_ENV=production
        networks:
          main:
            aliases:
              - mqttbroker1
      mqttbroker2:
        build: ./node_broker
        depends_on:
          - mongo
        ports:
          - "18831"
        environment:
          - NODE_ENV=production
        networks:
          main:
            aliases:
              - mqttbroker2
      mongo:
        container_name: mongo
        restart: always
        image: mongo
        volumes:
          - ./mongo/data:/data/db
        ports:
          - "27017:27017"
        networks:
          main:
            aliases:
              - mongo
    networks:
      main:
    

    and I use, this to connect via mqtt:

    const mqttClient = mqtt.connect('mqtt://proxy', { clientId: clientId });