Skip to main content

Mosquitto Docker: How to Set Up Eclipse Mosquitto MQTT Broker With Docker and Docker Compose

Step-by-step guide to deploying a production-ready Mosquitto MQTT broker using Docker containers. Includes authentication, TLS encryption, persistence configuration, and integration with Home Assistant.
Sep 17, 2025  · 14 min read

Setting up an MQTT broker from scratch shouldn't take hours of configuration and troubleshooting.

Eclipse Mosquitto is an open-source MQTT broker that implements MQTT v5, 3.1.1, and 3.1 protocols, making it perfect for IoT devices, home automation systems, cloud applications, and any message-driven architecture. But installing and configuring Mosquitto directly on your system often leads to dependency conflicts, permission issues, and platform-specific problems that eat up your development time. You end up spending more time fighting the setup than building your actual application.

Docker eliminates these headaches by providing a consistent, isolated environment for running Mosquitto across any platform. You can have a fully functional MQTT broker running in minutes, complete with custom configurations, authentication, and persistence.

In this guide, I'll walk you through deploying Eclipse Mosquitto using Docker and Docker Compose, configuring authentication and logging, setting up data persistence, and testing your broker with real MQTT clients.

Are you completely new to Docker? I recommend starting with our Introduction to Docker course to get a grasp of the fundamentals.

What Is Mosquitto and Why Use It in Docker

You don't need a heavy messaging system when all you want is fast, reliable communication between devices.

MQTT is a lightweight publish-subscribe protocol designed for situations where bandwidth is limited and reliability matters. Think IoT sensors, mobile apps, or any scenario where devices need to exchange small messages quickly without constant polling.

Mosquitto acts as the middleman - the broker - between publishers and subscribers. 

Publishers send messages to specific topics. Subscribers listen to those topics. Mosquitto handles the routing, ensuring messages get delivered to the right places without publishers and subscribers needing to know about each other.

Here's why Docker makes Mosquitto Docker setups even better:

  • Consistent setup across platforms: Windows, macOS, or Linux - the Docker container runs exactly the same way. No hunting down platform-specific installers or dealing with dependency conflicts.
  • Easy version management: You can pin specific Mosquitto versions using image tags, roll back if something breaks, and test new versions without touching your host system.
  • True portability: The same docker mosquitto setup works in development, staging, and production. Your local environment matches what's running on your servers.

Mosquitto comes in two flavors: the open-source version (which handles most use cases) and Cedalo's commercial Pro Edition with advanced features like clustering and enhanced security. For most projects, the open-source version does everything you need.

Next, I'll go over the prerequisites and then we'll dive into installing Mosquitto.

Prerequisites

You need Docker running on your system before you can deploy Mosquitto.

Docker Desktop works best for Windows and macOS users since it includes everything you need in one package. Linux users can install the Docker CLI directly through their package manager or from Docker's official repository.

Docker Compose isn't required, but it makes managing multi-container setups much easier. Most Docker Desktop installations include Compose by default. If you're on Linux, you might need to install it separately.

You'll also need basic command-line skills. Nothing fancy, just the ability to run commands, navigate directories, and edit text files.

Step-by-Step Setup

Getting mosquitto docker running takes three steps: create directories, run the container, and optionally set up Docker Compose for easier management.

Creating required directories

Mosquitto needs organized storage for its configuration, data, and logs.

Create them to get started:

mkdir mosquitto-docker
cd mosquitto-docker
mkdir config data logs

This gives you organized folders for Mosquitto's configuration files, persistent data, and log output.

Here's what each directory does:

  • /mosquitto/config stores mosquitto.conf and any additional configuration files
  • /mosquitto/data holds persistent message data and subscription information
  • /mosquitto/log contains Mosquitto's log files for debugging and monitoring

These directories get mounted as volumes inside the Docker container, so your settings and data survive container restarts.

Running Mosquitto with Docker

The basic Docker command gets Mosquitto running with proper port mapping and volume mounts.

docker run -d \
  --name mosquitto \
  -p 1883:1883 \
  -v $(pwd)/mosquitto/config:/mosquitto/config \
  -v $(pwd)/mosquitto/data:/mosquitto/data \
  -v $(pwd)/mosquitto/log:/mosquitto/log \
  eclipse-mosquitto:latest

Image 1 - Running Mosquitto with Docker

Image 1 - Running Mosquitto with Docker

Let me break down those flags:

  • -d runs the container in the background (detached mode)
  • --name mosquitto gives the container a friendly name for easy reference
  • -p 1883:1883 maps port 1883 on your host to port 1883 in the container
  • -v mounts local directories as volumes inside the container

Mosquitto 2.0+ runs in local-only mode by default. This means it only accepts connections from localhost unless you configure it otherwise. You'll need to create a configuration file to allow external connections.

Using Docker Compose

Mosquitto docker compose makes managing installation much simpler, especially when you're running multiple services.

Create a docker-compose.yml file and paste the following contents:

services:
  mosquitto:
    image: eclipse-mosquitto:latest
    container_name: mosquitto
    restart: unless-stopped
    ports:
      - "1883:1883"    # MQTT
      - "8883:8883"    # MQTTS (secure)
      - "9001:9001"    # WebSockets
    volumes:
      - ./mosquitto/config:/mosquitto/config
      - ./mosquitto/data:/mosquitto/data
      - ./mosquitto/log:/mosquitto/log

Start it with:

docker-compose up -d

Image 2 - Running Mosquitto with Docker Compose

Image 2 - Running Mosquitto with Docker Compose

The volume mappings work the same way as the Docker command, but Compose handles the complexity. The port configuration covers all common MQTT protocols: standard MQTT (1883), secure MQTTS (8883), and WebSocket connections (9001).

Compose really shines with multi-service setups. For example, if you're running Home Assistant, Node-RED, or other IoT tools alongside Mosquitto, you can define everything in one file and start all services together.

Let's dig deeper into the configuration next.

Do you find more advanced Docker concepts confusing? Our Intermediate Docker course goes above and beyond the fundamentals.

Configuring Mosquitto

Mosquitto won't accept external connections out of the box, you need a configuration file to do that.

Basic configuration (mosquitto.conf)

Create a mosquitto.conf file in your mosquitto/config directory and add the following:

# Basic listener configuration
listener 1883
allow_anonymous true

# WebSocket listener
listener 9001
protocol websockets
allow_anonymous true

# Persistence
persistence true
persistence_location /mosquitto/data/

# Logging
log_dest file /mosquitto/log/mosquitto.log
log_type error
log_type warning
log_type notice
log_type information

The allow_anonymous true setting lets clients connect without credentials. This works fine for development or internal networks, but you'll want to disable it for production environments. When you set allow_anonymous false, every client must authenticate with a username and password.

The WebSocket listener on port 9001 enables browser-based MQTT clients. Web applications can connect directly to your broker using JavaScript libraries like Paho MQTT.

Setting up authentication

Authentication requires creating a password file and updating your configuration.

Generate a password file inside the container:

docker exec -it mosquitto mosquitto_passwd -c /mosquitto/config/passwd username

Image 3 - Mosquitto authentication

Image 3 - Mosquitto authentication

This creates a new password file and prompts you to enter a password. For additional users, drop the -c flag:

docker exec -it mosquitto mosquitto_passwd /mosquitto/config/passwd another_user

Now, update your mosquitto.conf to force authentication:

# Disable anonymous access
allow_anonymous false

# Point to password file
password_file /mosquitto/config/passwd

# Basic MQTT listener
listener 1883

# WebSocket listener
listener 9001
protocol websockets

# Persistence
persistence true
persistence_location /mosquitto/data/

# Logging
log_dest file /mosquitto/log/mosquitto.log
log_type error
log_type warning
log_type notice
log_type information

The password file gets stored in your mounted config volume, so it persists between container restarts.

Enabling TLS/SSL

TLS encryption protects your MQTT traffic from eavesdropping and tampering.

Add these lines to your mosquitto.conf:

# Secure MQTT listener
listener 8883
cafile /mosquitto/config/ca.crt
certfile /mosquitto/config/server.crt
keyfile /mosquitto/config/server.key

# Secure WebSocket listener
listener 9002
protocol websockets
cafile /mosquitto/config/ca.crt
certfile /mosquitto/config/server.crt
keyfile /mosquitto/config/server.key

You'll need to obtain SSL certificates for your domain. Let's Encrypt provides free certificates, or you can use reverse proxies like Caddy Server that handle certificate generation automatically. Place your certificate files in the mosquitto/config directory so they're available inside the container.

Persistence and logging

Persistence saves messages and subscriptions to disk, while proper logging helps you debug connection issues.

You can configure persistence in mosquitto.conf this way:

# Enable persistence
persistence true
persistence_location /mosquitto/data/

# Save to disk every 300 seconds
autosave_interval 300

# Keep messages for offline clients
persistent_client_expiration 1d

As for the logging, here's how you can set up detailed logging:

# Log to file and stdout
log_dest file /mosquitto/log/mosquitto.log
log_dest stdout

# Choose what to log
log_type error
log_type warning
log_type notice
log_type information
log_type debug

# Log connection details
connection_messages true
log_timestamp true

The log_type options let you filter what gets logged:

  • error and warning for production monitoring
  • notice and information for general operational insights
  • debug for troubleshooting connection problems

Your volume mounts ensure both persistence data and logs survive container restarts. The data directory stores all persistent messages and subscription information, while the log directory keeps your debugging information accessible from the host system.

Configuration files give you complete control over Mosquitto's behavior without rebuilding containers.

Testing the Setup

Your broker isn't useful until you verify that clients can connect and exchange messages.

Using mosquitto_pub and mosquitto_sub

The mosquitto_pub and mosquitto_sub command-line tools provide the quickest way to test your broker.

Start by installing Mosquitto, depending on your platform:

  • Linux (Ubuntu/Debian): sudo apt-get install mosquitto-clients
  • macOS: brew install mosquitto
  • Windows: Download from the official Eclipse Mosquitto website or use WSL

Let's start testing it without authentication. You'll need two terminal windows or tabs. Run these commands in separate sessions:

# Subscribe to a topic (run this first)
mosquitto_sub -h localhost -p 1883 -t test/topic

# Publish a message (run in another terminal)
mosquitto_pub -h localhost -p 1883 -t test/topic -m "Hello MQTT"

In the publishing tab, you'll see this:

Image 4 - Publishing a message

Image 4 - Publishing a message

And in the subscribe tab, you'll immediately see the message:

Image 5 - Subscribing to a Mosquitto topic

Image 5 - Subscribing to a Mosquitto topic

If you require authentication, the commands are quite similar - you'll just have to pass username and password:

# Subscribe with username and password
mosquitto_sub -h localhost -p 1883 -t test/topic -u username -P password

# Publish with credentials
mosquitto_pub -h localhost -p 1883 -t test/topic -m "Authenticated message" -u username -P password

If you don't want to install the Mosquitto clients locally, run them inside your Docker container:

# Subscribe using the container
docker exec -it mosquitto mosquitto_sub -h localhost -t test/topic

# Publish using the container
docker exec -it mosquitto mosquitto_pub -h localhost -t test/topic -m "Container message"

You'll see this in the publishing tab:

Image 6 - Publishing a message without auth

Image 6 - Publishing a message without auth

And in the subscribe tab, you'll see the message:

Image 7 - Subscribing to a Mosquitto topic without auth

Image 7 - Subscribing to a Mosquitto topic without auth

Testing with MQTT clients

GUI clients make it easier to test complex scenarios and monitor ongoing message traffic.

MQTT Explorer provides a clean interface for browsing topics and sending messages. Connect to localhost:1883 and you'll see a tree view of all active topics. It's perfect for debugging message flows and understanding your topic structure.

Image 8 - MQTT Explorer app

Image 8 - MQTT Explorer app

MQTTX offers more advanced features like scripting and bulk message sending. Both clients support authentication, TLS connections, and WebSocket protocols.

Home Assistant users can test the MQTT integration directly from the developer tools. Add your broker details to the MQTT integration and use the built-in publish/subscribe interface.

For programmatic testing, the Paho MQTT Python client works well:

import paho.mqtt.client as mqtt

def on_connect(client, userdata, flags, rc):
    print(f"Connected with result code {rc}")
    client.subscribe("test/topic")

def on_message(client, userdata, msg):
    print(f"Received: {msg.payload.decode()}")

client = mqtt.Client()
# client.username_pw_set("username", "password")  # If using auth
client.on_connect = on_connect
client.on_message = on_message

client.connect("localhost", 1883, 60)
client.loop_forever()

Run this script in one terminal, then publish messages from another terminal or GUI client. The script will print any messages it receives, confirming your broker is routing traffic correctly.

Here's what you need to do to publish a message:

Image 9 - Publishing a message for the Python example

Image 9 - Publishing a message for the Python example

And you'll see this in the terminal session that has the Python script running:

Image 10 - Receiving a message for the Python example

Image 10 - Receiving a message for the Python example

Working publish and subscribe operations mean your Mosquitto Docker setup is ready for real applications.

Integrating Mosquitto Docker with Home Assistant

Running Mosquitto alongside Home Assistant in Docker creates a complete IoT messaging hub with zero network configuration hassles.

Docker Compose makes this simple. Both services can communicate through Docker's internal network without exposing additional ports or dealing with IP addresses.

Here's a complete docker-compose.yml that runs both services:

services:
  mosquitto:
    image: eclipse-mosquitto:latest
    container_name: mosquitto
    restart: unless-stopped
    ports:
      - "1883:1883"
      - "9001:9001"
    volumes:
      - ./mosquitto/config:/mosquitto/config
      - ./mosquitto/data:/mosquitto/data
      - ./mosquitto/log:/mosquitto/log
    networks:
      - homeassistant

  homeassistant:
    image: ghcr.io/home-assistant/home-assistant:stable
    container_name: homeassistant
    restart: unless-stopped
    ports:
      - "8123:8123"
    volumes:
      - ./homeassistant:/config
      - /etc/localtime:/etc/localtime:ro
    networks:
      - homeassistant
    depends_on:
      - mosquitto

networks:
  homeassistant:
    driver: bridge

The networks section creates a shared network where both containers can reach each other by name. Home Assistant can connect to mosquitto:1883 instead of using localhost or IP addresses.

Start both services with:

docker-compose up -d

Next, configure the MQTT integration through Home Assistant's web interface. Navigate to Settings > Devices & Services > Add Integration, then search for "MQTT."

Enter these connection details:

  • Broker: mosquitto (the container name)
  • Port: 1883
  • Username/Password: Your credentials if authentication is enabled
  • Keep the other settings as defaults

Click Submit and Home Assistant will test the connection. If successful, you'll see MQTT appear in your integrations list.

Image 11 - Mosquitto configuration with Homelab

Image 11 - Mosquitto configuration with Homelab

You can now add MQTT devices, create automations that publish messages, and monitor sensor data through topics. Home Assistant's MQTT integration handles device discovery automatically for compatible devices.

Troubleshooting Common Issues

Most docker mosquitto problems come down to permissions, ports, or configuration mistakes that block connections.

Permissions errors with mounted volumes 

These happen when the container can't write to your host directories. You'll see error messages like "Permission denied" or "Cannot create directory" in the logs.

Fix this by setting proper ownership on your directories:

sudo chown -R 1883:1883 mosquitto/

The Mosquitto container runs as user ID 1883, so your host directories need to match. On some systems, you might need to create the user first:

sudo useradd -u 1883 mosquitto
sudo chown -R mosquitto:mosquitto mosquitto/

Port conflicts

These occur when something else is using port 1883. Check what's running on that port:

# Linux/macOS
sudo lsof -i :1883

# Windows
netstat -an | findstr :1883

If another service is using the port, either stop it or map Mosquitto to a different port:

docker run -p 1884:1883 eclipse-mosquitto:latest

Local-only mode prevents external connections

This happens even when your container is running. Mosquitto 2.0+ defaults to accepting connections only from localhost unless you configure it otherwise.

Create a basic mosquitto.conf file to allow external connections:

listener 1883
allow_anonymous true

Place this file in your mosquitto/config directory and restart the container.

Empty directories on startup

These mean your volume mounts aren't working correctly. Check that your paths are absolute and the directories exist:

# Wrong - relative path might not work
-v ./mosquitto/config:/mosquitto/config

# Better - absolute path
-v $(pwd)/mosquitto/config:/mosquitto/config

Create the directories before starting the container:

mkdir -p mosquitto/{config,data,log}

Conflicting UIDs/GIDs between host and container

These will cause persistent permission problems. The container expects to run as user 1883, but your host system might have different ownership requirements.

Force the container to run as your user:

docker run --user $(id -u):$(id -g) eclipse-mosquitto:latest

Or adjust your host directory permissions to match the container's expectations. The container approach works better for development, while fixing host permissions works better for production deployments.

Check the container logs when things aren't working - they usually tell you exactly what's wrong.

Advanced: Mosquitto Pro Edition Features

The open-source Mosquitto covers most use cases, but enterprise environments need features that only the Pro Edition delivers.

Role-based user management lets you define granular permissions for different user groups. Instead of managing individual user access, you create roles like "sensor-readers," "actuator-controllers," or "admin-users" and assign permissions to entire roles. Users inherit the permissions of their assigned roles, making it easier to manage access across hundreds or thousands of devices.

You can restrict access by topic patterns, IP ranges, or time windows. This beats manually configuring ACL files when you're managing complex IoT deployments with different security requirements.

Advanced authentication options go beyond simple username/password combinations. JWT token authentication integrates with existing identity providers like Auth0, Okta, or your company's SSO system. LDAP integration connects directly to Active Directory or other enterprise directory services.

Deep inspection and monitoring gives you real-time visibility into message flows, connection patterns, and broker performance. The Pro Edition includes built-in dashboards that show which clients are consuming the most bandwidth, which topics have the highest message rates, and where bottlenecks are forming.

You get detailed metrics on message latency, queue depths, and client behavior patterns. This data helps you optimize topic structures and identify problematic clients before they impact the entire system.

Database and cloud service integrations eliminate the need for custom bridge applications. The Pro Edition can automatically forward messages to PostgreSQL, MongoDB, InfluxDB, AWS IoT Core, Azure IoT Hub, or Google Cloud IoT. You define routing rules that determine which messages go where based on topic patterns, message content, or client metadata.

Persistent queues handle high-volume scenarios where the standard Mosquitto persistence isn't enough. The Pro Edition can buffer millions of messages for offline clients and distribute the load across multiple broker instances. It includes automatic queue management that prevents memory exhaustion and maintains message ordering guarantees.

Clustering support lets you run multiple broker instances that share the message load and provide failover protection. When one broker goes down, clients automatically reconnect to healthy instances without losing messages or subscriptions.

The Pro Edition makes sense when you need enterprise-grade reliability and management features that would take months to build yourself.

Pros and Cons of Using Mosquitto in Docker

Docker makes deployment easier, but it's not the perfect solution for every scenario.

Pros

  • Cross-platform consistency eliminates the headaches of OS-specific installations. The same Docker command works on Windows, macOS, and Linux without hunting down different package managers or dealing with dependency conflicts. Your development setup matches production exactly, which means fewer surprises when you deploy.
  • Simple version upgrades happen by changing image tags. Instead of uninstalling the old version and hoping the upgrade doesn't break your config, you just pull a new image and restart the container. Rolling back takes seconds if something goes wrong.
  • Easy backup and migration comes from using volumes for your data. Copy the mosquitto directory to another machine, run the same Docker command, and you're back online. Moving between cloud providers or upgrading hardware becomes a simple file transfer.

Cons

Docker isn't all upside.

  • Volume permission issues plague certain operating systems, especially when switching between Windows and Linux hosts. You'll spend time fixing ownership problems and dealing with UID/GID mismatches that wouldn't exist with a native installation.
  • Extra configuration needed for production-grade security means Docker adds complexity rather than removing it. You need to manage network policies, container security contexts, and volume encryption on top of Mosquitto's own security features. Native installations let you use your OS's existing security frameworks directly.
  • Potential performance hit occurs in high-throughput scenarios where every microsecond matters. The container networking layer and volume mounts add overhead that native installations avoid. For most IoT applications this difference is negligible, but real-time industrial systems might notice the latency.

Docker wins when you need consistent deployments and easy management across different environments.

Conclusion

Running Mosquitto in Docker gives you a reliable MQTT broker that works consistently across all environments. It doesn't matter if you're prototyping IoT devices, building home automation systems, or connecting sensors in development, Docker eliminates setup complexity and lets you focus on your actual project.

If you plan to take Mosquitto to production, remember this:

  • Secure your broker before exposing it to the internet
  • Enable authentication with mosquitto_passwd, configure TLS encryption with proper certificates
  • Restrict access to only the clients that need it

An unsecured MQTT broker becomes an open door for attackers to monitor device communications or inject malicious commands.

For enterprise deployments that need advanced features like role-based access control, clustering, or LDAP integration, Mosquitto Pro Edition provides the management tools and scalability that go beyond the open-source version.

Ready to up your Docker and Kubernetes game? Enroll in our Containerization and Virtualization with Docker and Kubernetes skill track to build relevant skills and get hired.

Mosquitto Docker FAQs

What is the difference between running Mosquitto natively vs in Docker?

Docker provides cross-platform consistency and eliminates dependency conflicts that plague native installations. Your Mosquitto setup works identically on Windows, macOS, and Linux without hunting down platform-specific packages. Docker also makes version upgrades and rollbacks simple - just change the image tag and restart the container. However, native installations can offer slightly better performance for high-throughput scenarios.

Do I need Docker Compose to run Mosquitto, or can I use regular Docker commands?

You can absolutely run Mosquitto with regular Docker commands using docker run. Docker Compose just makes management easier, especially when you're running multiple services like Home Assistant or Node-RED alongside Mosquitto. If you're only running Mosquitto by itself, a simple docker run command works perfectly fine.

Is Mosquitto in Docker secure enough for production use?

Mosquitto Docker can be production-ready with proper configuration. You'll need to disable anonymous access, set up authentication with mosquitto_passwd, configure TLS encryption, and restrict network access to trusted clients only. The container itself doesn't add security vulnerabilities, but you're responsible for securing both Mosquitto's configuration and the Docker environment.

Why does my Mosquitto container start but refuse external connections?

Mosquitto 2.0+ defaults to local-only mode, which only accepts connections from localhost inside the container. You need to create a mosquitto.conf file with listener 1883 and allow_anonymous true (for testing) or proper authentication settings. Place this config file in your mounted /mosquitto/config directory and restart the container.

How do I fix "Permission denied" errors when Mosquitto tries to write to mounted volumes?

The Mosquitto container runs as user ID 1883, but your host directories might have different ownership. Run sudo chown -R 1883:1883 mosquitto/ to fix the ownership, or create the mosquitto user first with sudo useradd -u 1883 mosquitto then change ownership. On some systems, you can also run the container with --user $(id -u):$(id -g) to match your host user.


Dario Radečić's photo
Author
Dario Radečić
LinkedIn
Senior Data Scientist based in Croatia. Top Tech Writer with over 700 articles published, generating more than 10M views. Book Author of Machine Learning Automation with TPOT.
Topics

Top DataCamp Courses

Track

Containerization and Virtualization with Docker and Kubernetes

0 min
Learn the power of Docker and Kubernetes, this interactive track will allow you to build and deploy applications in modern environments.
See DetailsRight Arrow
Start Course
See MoreRight Arrow
Related

Tutorial

Kafka Docker Explained: Setup, Best Practices, and Tips

Learn how to set up Apache Kafka with Docker using Compose. Discover best practices, common pitfalls, and tips for development and testing environment
Derrick Mwiti's photo

Derrick Mwiti

Tutorial

How to Set Up and Configure MySQL in Docker

Learn how to set up and configure MySQL database inside Docker containers. The tutorial includes concepts such as connecting to MySQL servers, running MySQL clients to connect to containers, and so on.
Bex Tuychiev's photo

Bex Tuychiev

Tutorial

Docker Compose Guide: Simplify Multi-Container Development

Master Docker Compose for efficient multi-container application development. Learn best practices, scaling, orchestration, and real-world examples.
Derrick Mwiti's photo

Derrick Mwiti

Tutorial

Docker Proxy: The Complete Guide to Make Containers Work Behind Corporate Firewalls

Learn how to set up proxy configuration at every layer so your Docker operations work reliably behind enterprise firewalls.
Dario Radečić's photo

Dario Radečić

Tutorial

How to Deploy LLM Applications Using Docker: A Step-by-Step Guide

This tutorial teaches you how to use Docker to build and deploy a document Q&A application on the Hugging Face Cloud.
Abid Ali Awan's photo

Abid Ali Awan

Tutorial

Install Docker on Ubuntu: From Setup to First Container

It only takes a few commands from a fresh OS installation to running your first containerized application. Learn how to do this with this ultimate Docker Ubuntu setup guide.
Dario Radečić's photo

Dario Radečić

See MoreSee More