This repository sets up a cloud server for an Internet of Things (IoT) system that serves as an MQTT broker and data storage provider.
- Clone this Git repository.
- Install Docker and Docker Compose on the host machine.
- Configure authentication credentials for the MQTT broker by adding a password file to
mqtt-broker/passwd
. This file can be created by installing and running themosquitto_passwd
utility, which will then prompt for a password.mosquitto_passwd -c mqtt-broker/passwd <username>
- Find a domain registrar and point your selected domain at the server's IP address.
- Generate SSL certificates for your domain, then copy the certificates to the
mosquitto/certs
subdirectory:mkdir /mosquitto/certs cp -r -L /etc/letsencrypt/live/<domain> /mosquitto/certs
- Note that the files under
/etc/letsencrypt/live/<domain>
are symbolic links to those under/etc/letsencrypt/archive/<domain>
, so the-L
option is used to follow the links and copy the contents of the actual files.
- Note that the files under
- Change the ownership and group of the
mosquitto/certs
subdirectory so that it belongs to user1883
:chown -R 1883:1883 /mosquitto/certs
- This step is necessary because as of V2.0, Mosquitto loads TLS certificates as an unprivileged user instead of the root user.
Since the
eclipse-mosquitto
Docker image runs Mosquitto as user1883
(mosquitto
), this user must be able to access the certificates.
- This step is necessary because as of V2.0, Mosquitto loads TLS certificates as an unprivileged user instead of the root user.
Since the
- Start the application by running
docker-compose
from the root project directory:docker-compose up --detach
To test the connection to the MQTT broker from any machine, run the following in separate terminals:
mosquitto_sub -h <domain> -p 8883 -u <username> -P <password> -t test
mosquitto_pub -h <domain> -p 8883 -u <username> -P <password> -t test -m "Hello World!"
Note that connections must be carried out over TLS, so we use the domain name (instead of an IP address)
and specify port 8883
(instead of the default 1883
).
The MQTT broker can also receive connections via WebSockets over TLS (WSS). Example code using the MQTT.js client library is given below:
const client = mqtt.connect(`wss://${MQTT_HOST}:9001`, {
username: MQTT_USERNAME,
password: MQTT_PASSWORD,
});
const topics = ['test', 'helloworld'];
client.on('connect', () => {
console.log('Connected');
client.subscribe(topics, (err, granted) => {
console.log(`Subscribed to topic(s) '${granted.map((grant) => grant.topic).join("', '")}'`);
client.publish('test', 'This works!', {}, (err) => {
if (err) {
console.error('Failed to publish message', err);
}
});
});
});
client.on('message', (topic, message, packet) => {
console.log(`[${topic}] Received Message:`, message.toString(), packet);
});