A step-by-step guide for starting a mosquitto broker service in a container with docker-compose
Prerequisites
Before we start, make sure you have the following installed on your machine:
- Docker
- docker-compose
You can install the prerequisites following this tutorial.
- Open your terminal and create a new directory called
mosquitto
:
mkdir mosquitto
- Change to the
mosquitto
directory:
cd mosquitto
- Create the
config
folder and themosquitto.conf
andpassword.txt
files inside it (with the content as follows):
mkdir config
echo 'listener 1883
persistence true
persistence_location /mosquitto/data/
log_dest file /mosquitto/log/mosquitto.log
allow_anonymous false
password_file /mosquitto/config/password.txt' > config/mosquitto.conf
echo "admin:\$7\$101\$xuOfObQdv0Hi2p0A\$o+J3vzbpm0hekukYw73tT3fiB2Ogi1UCJgbzNyFA0GOgxAo79hqfTeXVr062KoD5nCphwV+1V/NxlMzwnV5Kvg==" > config/password.txt
- Create the
log
folder and themosquitto.log
file inside it:
mkdir log
touch log/mosquitto.log
- Set the read and write permissions for all users for the following files:
chmod o+w log/mosquitto.log
chmod 766 -R config
- Create the
docker-compose.yml
file with the following content:
version: '3.8'
networks:
mqtt-net:
driver: bridge
ipam:
driver: default
config:
- subnet: 172.100.10.0/24
services:
mqtt-broker:
image: eclipse-mosquitto:latest
user: mosquitto
volumes:
- type: bind
source: ./config/
target: /mosquitto/config/
read_only: false
- type: bind
source: ./log/
target: /mosquitto/log/
read_only: false
- type: volume
source: data
target: /mosquitto/data/
ports:
- target: 1883
published: 1883
protocol: tcp
mode: host
- target: 9001
published: 9001
protocol: tcp
mode: host
networks:
mqtt-net:
ipv4_address: 172.100.10.10
mqtt-pub:
image: eclipse-mosquitto:latest
command: sh -c "mosquitto_pub -h mqtt-broker -t test -m 'Hello World' -u admin -P password"
depends_on:
- mqtt-broker
networks:
mqtt-net:
ipv4_address: 172.100.10.11
mqtt-sub:
image: eclipse-mosquitto:latest
command: sh -c "mosquitto_sub -h mqtt-broker -t test -u admin -P password"
depends_on:
- mqtt-broker
networks:
mqtt-net:
ipv4_address: 172.100.10.12
volumes:
data:
name: "mqtt-broker-data"
Note that we have assigned a static IP address of 172.100.10.10
to the mqtt-broker
service.
- Build and start the containers by running the following command:
docker-compose up --build
This should bring up 3 services, namely mqtt-broker
, mqtt-pub
, and mqtt-sub
. The mqtt-pub
service will immediately exit since it exits after publishing a message.
The default username and password for mqtt-broker
are admin
and password
, respectively.
- We can now publish messages using the
mqtt-pub
service:
docker compose run mqtt-pub sh -c "mosquitto_pub -h mqtt-broker -t test -m 'Hello World' -u admin -P password"
docker compose run mqtt-pub sh -c "mosquitto_pub -h mqtt-broker -t test -m 'Message 2' -u admin -P password"
docker compose run mqtt-pub sh -c "mosquitto_pub -h mqtt-broker -t test -m 'Message 3' -u admin -P password"
The output should be as follows:
mqtt-mqtt-sub-1 | Hello World
mqtt-mqtt-sub-1 | Message 2
mqtt-mqtt-sub-1 | Message 3
- To change the password of the
admin
user (after changing the password, the service needs to be restarted):
docker compose exec mqtt-broker mosquitto_passwd -b /mosquitto/config/password.txt admin NEWPASSWORD
Restart the container:
docker compose restart mqtt-broker
-
Since we changed the
admin
password, we will no longer be able to start themqtt-pub
service withdocker compose up mqtt-sub
. We need to start it using the following command:
docker compose run mqtt-sub sh -c "mosquitto_sub -h mqtt-broker -t test -u admin -P CHANGED_PASSWORD"
Now we can publish a message (using another terminal) and see it reflected in the
mqtt-sub
container service:
docker compose run mqtt-pub sh -c "mosquitto_pub -h mqtt-broker -t test -m 'Hello World' -u admin -P CHANGED_PASSWORD"
Top comments (1)
Your indentation is all screwed up. Any chance you can fix it for future travellers?
Docker compose build errors out because you are defining the driver twice, once as bridge then again as default.
Should be:
You also get the message "volumes must be a mapping", this is because there is an indentation error on the
data:
field.Should be:
But after all of that still getting an invalid IPv4 address for the subscriber.
Any ideas?