Config nginx to reverse proxy for mqtt communication

Viewed 5101

I have an MQTT (EMQX) server running on an ip and a port. And I communicate directly between my service and that port using the nodejs MQTT library.

I want to use a reverse proxy (nginx) to be able to use a DNS in order to prune the communication.

At this moment my nginx is configured like this:

events { worker_connections 1024; }

stream {

    upstream websocket {
        server ******:7053;
    }
 
    server {

        listen 8888;
 
        proxy_pass websocket;


    }
}

http {

    server {
        
        listen 884;
        server_name *******;.
        error_log /var/log/errors.log;
        
        location / {
            proxy_pass *******;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
            proxy_set_header Host $host;

        }

    } 

}

So when I try to connect through port 8888 the nginx always timeout

2020/12/03 16:23:48 [error] 22#22: *31 upstream timed out (110: Connection timed out) while connecting to upstream, client: 89.155.0.10, server: 0.0.0.0:8888, upstream: "192.16.102.26:7053", bytes from/to client:0/0, bytes from/to upstream:0/0

both services are in docker containers. and are started by a docker compose.

the compose for MQTT service is:

version: "2.1"


services:

  mqtt-broker:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: evio_mqtt_broker
    environment:
      - EMQX_LISTENER__SSL__EXTERNAL=8883
      - EMQX_DASHBOARD__LISTENER__HTTP=18083

      - EMQX_LOADED_PLUGINS="emqx_auth_username,emqx_recon,emqx_retainer,emqx_management,emqx_dashboard"

      - EMQX_LISTENER__SSL__EXTERNAL__TLS_VERSIONS=tlsv1.2
      #- EMQX_LISTENER__SSL__EXTERNAL__KEYFILE=etc/certs/key.pem
      #- EMQX_LISTENER__SSL__EXTERNAL__CERTFILE=etc/certs/cert.pem
      #- EMQX_LISTENER__SSL__EXTERNAL__CACERTFILE=etc/certs/cacert.pem
      - EMQX_LISTENER__SSL__EXTERNAL__VERIFY=verify_peer
      #- EMQX_LISTENER__SSL__EXTERNAL__FAIL_IF_NO_PEER_CERT=true
      - EMQX_LISTENER__SSL__EXTERNAL__REUSE_SESSIONS=on
      - EMQX_LISTENER__SSL__EXTERNAL__HONOR_CIPHER_ORDER=on

      - EMQX_ALLOW_ANONYMOUS=false
      - EMQX_AUTH__USER__1__USERNAME=****
      - EMQX_AUTH__USER__1__PASSWORD=****
      #- EMQX_AUTH__USER__2__USERNAME=umdc
      #- EMQX_AUTH__USER__2__PASSWORD=umdc_buddy

      - EMQX_DASHBOARD__DEFAULT_USER__PASSWORD=****
    ports:
      - "7053:1883"   # MQTT Port
      - "8883:8883"   # MQTT SSL Port
      #- "8083:8083"   # MQTT WebSocket Port
      #- "8084:8084"   # MQTT WebSocket SSL Port
      #- "8080:8080"   # HTPP Management Port
      - "1884:18083" # Web Dashboard Port
    logging:
      driver: "json-file"
      options:
        max-size: "50m"
        max-file: "3"
    networks:
      - evio_network
    stop_signal: SIGKILL

networks:
    evio_network:

and for nginx are:

version: "2.0"

networks:
  evio_network:

services:
  reverse_proxy:
    container_name: reverse_proxy
    image: nginx
    networks:
      - evio_network
    ports:
      - 8888:8888
      - 8843:8843
      - 1883:1883
      - 8883:8883
    volumes:
      - /home/evio/src/evio_nginx_reverse_proxy/config/nginxDEV.conf:/etc/nginx/nginx.conf
    restart: always

Do I have to change anything in mqtt or is something wrong with my reverse proxy?

1 Answers

As hashed out in the comments.

The problem here was that the 2 services were being started from seperate docker-compose files. While they were both binding to networks with the same name, those networks were separate because they were being prefixed by different orchestration names.

There are 2 solutions to this problem:

  1. Combine the 2 docker compose files, this will mean that they are then in the same namespace and will share the common named network.
  2. Create a "external" network and reference this from both files.

For the second option you use the docker network command to create the network, e.g. docker network create evio_network and then at the end of each compose file include the following:

networks:
  evio_network:
    external:
      name: "evio_network"
Related