How to Self-Host Mosquitto MQTT Broker
What Is Mosquitto?
Eclipse Mosquitto is a lightweight open-source MQTT message broker. MQTT is the standard messaging protocol for IoT and home automation — it’s how your Zigbee sensors, smart switches, and automation platforms (Home Assistant, Node-RED, OpenHAB) talk to each other. Mosquitto is the most widely deployed MQTT broker for self-hosting: tiny resource footprint, rock-solid stability, and dead-simple to run.
Prerequisites
- A Linux server (Ubuntu 22.04+ recommended)
- Docker and Docker Compose installed (guide)
- 50 MB of free disk space
- 64 MB of RAM (minimum — Mosquitto is extremely lightweight)
- Understanding of MQTT concepts (topics, publish/subscribe) is helpful but not required
Docker Compose Configuration
Create a project directory and configuration files:
mkdir -p mosquitto/config mosquitto/data mosquitto/log
Create mosquitto/config/mosquitto.conf:
# Eclipse Mosquitto Configuration
# Network listeners
listener 1883
protocol mqtt
# WebSocket listener (optional — useful for browser-based MQTT clients)
listener 9001
protocol websockets
# Authentication — REQUIRED since Mosquitto 2.0
# Without this, Mosquitto rejects all connections by default
allow_anonymous false
password_file /mosquitto/config/password_file
# Persistence — retain messages across restarts
persistence true
persistence_location /mosquitto/data/
# Logging
log_dest file /mosquitto/log/mosquitto.log
log_type all
connection_messages true
Create docker-compose.yml:
services:
mosquitto:
image: eclipse-mosquitto:2.0.20
container_name: mosquitto
restart: unless-stopped
ports:
- "1883:1883" # MQTT
- "9001:9001" # MQTT over WebSockets (optional)
volumes:
- ./mosquitto/config:/mosquitto/config
- ./mosquitto/data:/mosquitto/data
- ./mosquitto/log:/mosquitto/log
user: "1883:1883"
Create a password file with your first user:
docker run --rm -v ./mosquitto/config:/mosquitto/config eclipse-mosquitto:2.0.20 \
mosquitto_passwd -c /mosquitto/config/password_file myuser
You’ll be prompted to enter a password. To add more users later (without the -c flag, which creates a new file):
docker run --rm -v ./mosquitto/config:/mosquitto/config eclipse-mosquitto:2.0.20 \
mosquitto_passwd /mosquitto/config/password_file anotheruser
Start the broker:
docker compose up -d
Initial Setup
Mosquitto has no web UI — it’s a pure message broker. After starting, verify it’s running:
docker compose logs mosquitto
You should see output like:
mosquitto version 2.0.20 starting
Config loaded from /mosquitto/config/mosquitto.conf
Opening ipv4 listen socket on port 1883.
Opening ipv4 listen socket on port 9001.
mosquitto version 2.0.20 running
Test the connection with mosquitto_pub and mosquitto_sub (from the container):
# In one terminal, subscribe to a test topic:
docker exec mosquitto mosquitto_sub -u myuser -P 'yourpassword' -t 'test/topic'
# In another terminal, publish a message:
docker exec mosquitto mosquitto_pub -u myuser -P 'yourpassword' -t 'test/topic' -m 'Hello MQTT'
The subscriber terminal should display “Hello MQTT”.
Configuration
Authentication Options
Password file (shown above) is the simplest. For more advanced setups:
ACL (Access Control Lists) — restrict which users can publish/subscribe to which topics. Create mosquitto/config/acl_file:
# User "sensors" can only publish to sensor topics
user sensors
topic write sensors/#
# User "dashboard" can read everything
user dashboard
topic read #
# User "admin" has full access
user admin
topic readwrite #
Add to mosquitto.conf:
acl_file /mosquitto/config/acl_file
TLS/SSL Encryption
For encrypted connections, add to mosquitto.conf:
# TLS listener (replaces or supplements port 1883)
listener 8883
protocol mqtt
cafile /mosquitto/config/certs/ca.crt
certfile /mosquitto/config/certs/server.crt
keyfile /mosquitto/config/certs/server.key
Mount your certificates into the config directory.
Retained Messages and QoS
MQTT supports three Quality of Service levels:
- QoS 0: Fire and forget (fastest, no delivery guarantee)
- QoS 1: Delivered at least once (may duplicate)
- QoS 2: Delivered exactly once (slowest, guaranteed)
Retained messages are stored by the broker and sent to new subscribers immediately. This is how dashboards get the current state of sensors on connect.
Advanced Configuration (Optional)
Bridge to Another Broker
Connect your Mosquitto instance to another MQTT broker (useful for linking sites or connecting to cloud services):
# Bridge configuration
connection cloud-bridge
address remote-broker.example.com:8883
topic # out 0
topic # in 0
bridge_cafile /mosquitto/config/certs/ca.crt
remote_username bridge_user
remote_password bridge_pass
Max Connections and Message Size
# Limit simultaneous connections (default: unlimited)
max_connections 1000
# Maximum message payload size in bytes (default: 268435456 = 256 MB)
message_size_limit 1048576
Logging Levels
# Options: debug, error, warning, notice, information, subscribe, unsubscribe, all
log_type error
log_type warning
log_type notice
Reverse Proxy
MQTT uses its own TCP protocol, not HTTP, so standard HTTP reverse proxies don’t apply to port 1883. However, the WebSocket listener (port 9001) can be proxied:
Nginx Proxy Manager / Nginx:
location /mqtt {
proxy_pass http://mosquitto:9001;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
For the native MQTT port, use a TCP/stream proxy or expose the port directly. See Reverse Proxy Setup for general guidance.
Backup
Back up these directories:
mosquitto/config/— configuration, password file, ACL file, certificatesmosquitto/data/— persistent message store and retained messages
tar -czf mosquitto-backup-$(date +%Y%m%d).tar.gz mosquitto/
The data directory contains the persistence database (mosquitto.db). Without it, retained messages and durable subscriptions are lost on restore. See Backup Strategy for a comprehensive approach.
Troubleshooting
Connection Refused
Symptom: Clients get “Connection refused” when connecting to port 1883.
Fix: Since Mosquitto 2.0, anonymous connections are rejected by default. You must either:
- Set up a password file (recommended), or
- Add
allow_anonymous truetomosquitto.conf(not recommended for production)
Check logs: docker compose logs mosquitto
Permission Denied on Config/Data Directories
Symptom: Mosquitto fails to start with “Error: Unable to open config file” or permission errors on data/log directories.
Fix: The Mosquitto container runs as UID 1883. Set ownership:
sudo chown -R 1883:1883 mosquitto/
Clients Disconnect Immediately After Connecting
Symptom: Clients connect then immediately disconnect.
Fix: Check for duplicate client IDs. MQTT only allows one connection per client ID — when a second client connects with the same ID, the first is kicked off. Ensure each client uses a unique ID.
WebSocket Connection Fails
Symptom: Browser-based MQTT clients can’t connect on port 9001.
Fix: Ensure the WebSocket listener is configured in mosquitto.conf:
listener 9001
protocol websockets
And that the port is mapped in docker-compose.yml. If behind a reverse proxy, verify WebSocket upgrade headers are passed through.
Messages Not Persisting After Restart
Symptom: Retained messages disappear after container restart.
Fix: Ensure persistence true is set in mosquitto.conf and that the /mosquitto/data/ volume is mounted correctly. Check that the container has write permissions to the data directory.
Resource Requirements
- RAM: ~10-20 MB idle, ~50-100 MB under moderate load (thousands of messages/second)
- CPU: Negligible for home automation use. Handles 10,000+ messages/second on a single core
- Disk: Minimal. A few MB for persistence unless storing large retained messages
Mosquitto is one of the lightest self-hosted services you can run. It works on a Raspberry Pi Zero.
Verdict
Mosquitto is the default choice for a self-hosted MQTT broker, and for good reason. It’s tiny, stable, and does exactly one thing well. Every major home automation platform supports it. If you’re running Home Assistant, Zigbee2MQTT, Node-RED, or any IoT setup, you almost certainly need an MQTT broker, and Mosquitto is the one to use.
The only reason to look elsewhere is if you need clustering (multiple broker nodes) or a built-in management UI — in which case, check out EMQX or NanoMQ. For a single-server home automation setup, Mosquitto is unbeatable.
Related
Get self-hosting tips in your inbox
Get the Docker Compose configs, hardware picks, and setup shortcuts we don't put in articles. Weekly. No spam.
Comments