Problem with Docker and MQTT

Hello
I want to install Home Assistant on Docker with docker-compose. When I want only expose selected ports to host, I have problem with connection HA<->MQTT. When I use network_mode: host for HA image, it works fine. I can show my problematic docker-compose:

services:
  mosquitto:
    image: eclipse-mosquitto
    volumes:
      - ./mosquitto-config:/mosquitto/config
  zigbee2mqtt:
    image: koenkk/zigbee2mqtt
    volumes:
      - ./zigbee2mqtt:/app/data
    devices:
      - /dev/ttyUSB0:/dev/ttyUSB0
    depends_on:
      - mosquitto
  homeassistant:
    image: ghcr.io/home-assistant/home-assistant:2021.12.9
    volumes:
      - ./config:/config
      - /etc/localtime:/etc/localtime:ro
    ports:
      - "8123:8123"
    depends_on:
      - mosquitto

In HA configuration.yaml I have:

mqtt:
  broker: mosquitto
  discovery: true
  birth_message:
    topic: 'hass/status'
    payload: 'online'
  will_message:
    topic: 'hass/status'
    payload: 'offline'

After start, I receive error “2022-01-21 15:59:28 ERROR (MainThread) [homeassistant.components.mqtt] Failed to connect to MQTT server due to exception: [Errno 99] Address not available”

When I change my docker-compose to something like this:

services:
  mosquitto:
    image: eclipse-mosquitto
    volumes:
      - ./mosquitto-config:/mosquitto/config
  zigbee2mqtt:
    image: koenkk/zigbee2mqtt
    volumes:
      - ./zigbee2mqtt:/app/data
    devices:
      - /dev/ttyUSB0:/dev/ttyUSB0
    depends_on:
      - mosquitto
  homeassistant:
    image: ghcr.io/home-assistant/home-assistant
    volumes:
      - ./config:/config
      - /etc/localtime:/etc/localtime:ro
    network_mode: host
    depends_on:
      - mosquitto

So with network_mode: host only for homeassistant image and change config to

mqtt:
  broker: localhost
  discovery: true
  birth_message:
    topic: 'hass/status'
    payload: 'online'
  will_message:
    topic: 'hass/status'
    payload: 'offline'

It works… Why? Any ideas? I should map more ports from HA?

1 Like

Switch to host network. Although HA will in general run without it, features like discovery and many integrations will not work, as they open (random) ports.

I am actually wondering why it works when you set host network on the HA container, but do not open port 1883 on the mosquitto container …

Docker networking maybe?

Each docker container gets IP in docker network

HA 172.2.0.17
Mosquito 172.2.0.19

Or some address like those.

All ports are exposed between them so HA can connect to mosquito at 172.2.0.19:1883 without issue. If you give your container a host name in docker like “mqtt” for mosquito it will be accessible at mqtt:1883. This is best as docker IP may change if you recreate container

Additionally you may create individual docker networks to limit each containers access to other containers via network

I know, but with network_mode: host you take that container of the docker network. And since the MQTT container does not use host-network, HA cannot connect to it using „localhost“

Thanks, I know that I can switch to host network, but it’s not answer for my question :slight_smile: I don’t want to use it, because I have other services on same server, so I want to fully control used ports. Why it doesn’t work with opened port 8123 and MQTT access via docker network?

Okay,

so the issue you are facing is, that HA cannot access the MQTT service from the same docker-compose network stack, if HA is not using the host network. I think the reason is, that you don’t expose the MQTT port (1883) for the Mosquitto container. Try something like:

services:
  mosquitto:
    expose:
      - 1883
    image: eclipse-mosquitto
    volumes:
      - ./mosquitto-config:/mosquitto/config

You also say, that it does work however, if you put only HA to host networking and that what makes me wonder. I’d expect that you need to add a ports statement to the MQTT service, like

services:
  mosquitto:
    ports:
      - 1883:1883
    image: eclipse-mosquitto
    volumes:
      - ./mosquitto-config:/mosquitto/config

Reason: MQTT container is still local to the docker-compose network. When setting network_mode: host for the HA container, you take it off the compose network. To connect to the MQTT service, that service must bind a host port to the container port 1883. Then, HA (and any other client) can connect to MQTT.

Name resolution by container name only work if you define a common docker network in your compose.

  mosquitto:
    image: eclipse-mosquitto
    networks:
    - homeassistant
[...]
  homeassistant:
    image: ghcr.io/home-assistant/home-assistant:2021.12.9
    networks:
    - homeassistant

There is a network created by docker-compose for all services of the same stack.

Thats not true. I have also postgresql in docker-compose, in HA recorder config I use service name from compose as db host and it works

Exactly. I added expose with 1883 to mosquitto in docker-compose and I tried to set broker host in HA to 172.17.0.1 or mosquitto and it doesn’t work… Still same error. I have postgres also in docker-compose, I don’t have configured ports/expose and it works from HA - in recorder I use service name as host.

Mmm… yeah, could be.

OTOH, if container name is not set in the compose, IIRC, the generated container name is something like “service-image-number”, and that will be the DNS name.
docker ps will tell

Yes, and docker inspect shows, that there will be a network alias using the service‘s name. So „mosquitto“ is valid.

1 Like

names
docker ps shown automatically generated names (directory name + service name), but it doesn’t matter.

I changed network_mode to host again for HA container and look:

$ docker-compose exec homeassistant ping mosquittooooo
ping: bad address ‘mosquittooooo’

mosquittooooo is an invented name that doesn’t exists - ping doesnt work.

$ docker-compose exec homeassistant ping mosquitto
PING mosquitto (172.18.0.3): 56 data bytes
64 bytes from 172.18.0.3: seq=0 ttl=64 time=0.268 ms
64 bytes from 172.18.0.3: seq=1 ttl=64 time=0.197 ms
64 bytes from 172.18.0.3: seq=2 ttl=64 time=0.194 ms
^C
— mosquitto ping statistics —
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 0.194/0.219/0.268 ms

and it works - HA container see mosquitto container by docker service name

In HA container logs still:

homeassistant_1 | 2022-01-22 12:21:03 ERROR (MainThread) [homeassistant.components.mqtt] Failed to connect to MQTT server due to exception: [Errno 99] Address not available

How about removing the mqtt section from configuration.yaml and using the MQTT integration from UI? The configuration flow of that integration may provide more information.

BTW: The „non-UI“ configuration only mentions the broker‘s IP address, not a host name. That would match the error message.

Yes, you’re right! I don’t know how and why, but when I added MQTT integration from UI and typed host mosquitto it works without network_mode: host for container. I wouldn’t think to check it. Thank you very much

1 Like