pythonflaskdocker-composemqttflask-restx

Python, Mqtt : can publish but can't receive message on docker


I'm running two dockers : one for the mqtt server using mosquitto the other using flask_mqtt

the flask container is receiving the CONNACK and is sending the subscribe to the broker but never get any SUBACK

however it manages to publish hello word to /home/mytopic (mqtt-explorer proof)

this is quite strange because it works without any problem outside of a docker

here is the docker compose :

services:
  mqtt:
    container_name: mqtt_container
    image: eclipse-mosquitto:latest
    networks:
      - local_net
    ports:
      - "1883:1883"
    volumes:
      - ./MqttServer/:/mosquitto/config/:rw
  flask:
    container_name: flask_container
    build:
      context: Api
      dockerfile: Dockerfile
    networks:
      - local_net
    ports:
      - "80:80"

networks:
  local_net:
    external: false

the flask dockerfile :

FROM python:latest

COPY requirements.txt /
RUN pip3 install -r /requirements.txt

COPY . /app
WORKDIR /app

# ENTRYPOINT ["gunicorn", "main:app", "-w", "1", "-b", "0.0.0.0:80"]
ENTRYPOINT ["python", "main.py"]

and the main.py

from flask import Flask
from flask_mqtt import Mqtt
from flask_restx import Api, Resource

app = Flask(__name__)

app.config['MQTT_BROKER_URL'] = "mqtt"
app.config['MQTT_BROKER_PORT'] = 1883
app.config['MQTT_KEEPALIVE'] = 60

mqtt = Mqtt(app)

api = Api(
    app=app,
    title='xxx',
    description='yyy',
    version='1.0.0',
)


@mqtt.on_connect()
def handle_connect(client, userdata, flags, rc):
    if rc == 0:
        print("connection established")
        mqtt.subscribe('home/mytopic')
    else:
        print("connection error")


@mqtt.on_message()
def handle_mqtt_message(client, userdata, message):
    print("i'm here")
    data = dict(
        topic=message.topic,
        payload=message.payload.decode()
    )
    print(data)


@mqtt.on_log()
def handle_logging(client, userdata, level, buf):
    print(buf)


@api.route('/test')
class Airflow(Resource):
    def get(self):
        mqtt.publish('home/mytopic', "hello world")

    def post(self):
        pass


if __name__ == '__main__':
    app.run(host="0.0.0.0", port=80, debug=False, use_reloader=False)


Solution

  • Maybe one of the containers is missing an exposed port. In doubt, try linking them by adding a links: tag in your compose like this :

    version: "3.6"
    services:
      mqtt:
        container_name: mqtt_container
        image: eclipse-mosquitto:latest
        ports:
          - 1883:1883
        volumes:
          - ./MqttServer/:/mosquitto/config/:rw
        links:
            - flask
      flask:
        container_name: flask_container
        build:
          context: Api
          dockerfile: Dockerfile
        ports:
          - 5000:5000