#docker #docker-compose #mqtt #mosquitto
#docker #docker-создать #mqtt #mosquitto
Вопрос:
Я пытаюсь запустить настройку локального брокера mosquitto, издателя и подписчика через docker и docker-compose, но издатель не может подключиться к брокеру. Однако подключение к локальному брокеру через cli работает нормально. При запуске ниже настройки получаю следующую ошибку.
{ Error: connect ECONNREFUSED 127.0.0.1:1883
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1088:14)
errno: 'ECONNREFUSED',
code: 'ECONNREFUSED',
syscall: 'connect',
address: '127.0.0.1',
port: 1883 }
Локальная настройка в dockerized:
docker-compose.yml:
version: "3.5"
services:
publisher:
hostname: publisher
container_name: publisher
build:
context: ./
dockerfile: dev.Dockerfile
command: npm start
networks:
- default
depends_on:
- broker
broker:
image: eclipse-mosquitto
hostname: mosquitto-broker
container_name: mosquitto-broker
networks:
- default
ports:
- "1883:1883"
networks:
default:
dev.Dockerfile:
FROM node:11-alpine
RUN mkdir app
WORKDIR app
COPY package*.json ./
RUN npm ci
COPY ./src ./src
CMD npm start
src/index.js:
const mqtt = require("mqtt");
const client = mqtt.connect("mqtt://localhost:1883");
client.on("connect", () => {
console.log("Start publishing...");
client.publish("testTopic", "test");
});
client.on("error", (error) => {
console.error(error);
});
Однако, если я подключаюсь к брокеру mosquitto через mqtt-js cli, он работает так, как ожидалось. Например.
mqtt sub -t 'testTopic' -h 'localhost'
и mqtt pub -t 'testTopic' -h 'localhost' -m 'from MQTT.js'
.
Чего мне не хватает?
Ответ №1:
ваш контейнер publisher и брокер работают в двух разных контейнерах, что означает, что это две разные машины, каждая из которых имеет свой собственный IP.
вы не можете вызвать службу брокера из своего контейнера publisher с помощью localhost: 1883 и наоборот, из контейнера broker в publisher
Чтобы получить доступ к контейнеру брокера, вы должны вызвать IP-адрес контейнера, или имя, или название службы
в вашем случае измените mqtt.connect("mqtt://localhost:1883");
значение на mqtt.connect("mqtt://broker:1883");
и попробуйте
Ответ №2:
publisher
И broker
выполняются в разных контейнерах, что означает, что у них разные IP-адреса.
Когда издатель пытается связаться с брокером по адресу localhost:1883
, обычно получает ECONNREFUSED
, следовательно, брокер не находится в том же контейнере.
Вы должны заменить 127.0.0.1
или localhost
именем службы брокера ( broker
в данном случае). Имя службы будет преобразовано в правильный IP-адрес контейнера брокера.
Ответ №3:
в вашем index.js вы должны изменить «localhost» на «broker». Когда внутри контейнера «localhost» будет разрешен для этого конкретного контейнера, поэтому вы всегда должны использовать вместо этого имя службы, а docker позаботится о маршрутизации к этой конкретной службе. Также по умолчанию все службы в одном и том же файле компоновки добавляются в одну сеть, поэтому нет необходимости указывать это.
Итак, в основном измените это: const client = mqtt.connect(«mqtt://localhost:1883»);
Для этого: const client = mqtt.connect(«mqtt://брокер: 1883»);
Комментарии:
1. Спасибо за дополнительную подсказку о конфигурации сети