Docker es la forma más rápida de tener un broker MQTT desechable y reproducible. La imagen oficial eclipse-mosquitto es pequeña y está bien mantenida, pero sus valores por defecto sorprenden a casi todo el mundo la primera vez: sin un archivo de configuración, no puedes conectarte desde fuera del contenedor. Esta guía monta Mosquitto en Docker como es debido — con volúmenes persistentes, puertos TCP y WebSocket y autenticación por contraseña.
1. Crea la estructura de carpetas
La imagen espera tres directorios bajo /mosquitto. Replícalos en el host:
mkdir -p mosquitto/config mosquitto/data mosquitto/log
touch mosquitto/config/mosquitto.conf| Carpeta en el host | Ruta en el contenedor | Propósito |
|---|---|---|
./mosquitto/config | /mosquitto/config | mosquitto.conf, archivo de contraseñas, archivo ACL, certificados |
./mosquitto/data | /mosquitto/data | Base de datos de persistencia (mensajes retenidos, sesiones) |
./mosquitto/log | /mosquitto/log | Archivos de log, si registras en un archivo |
2. Escribe un mosquitto.conf mínimo
Mosquitto 2.x solo escucha en localhost cuando no hay ningún listener configurado — dentro de un contenedor eso significa que nadie puede llegar a él. Esta configuración abre MQTT en el 1883 y WebSockets en el 9001:
# MQTT over TCP
listener 1883
# MQTT over WebSockets
listener 9001
protocol websockets
persistence true
persistence_location /mosquitto/data/
log_dest file /mosquitto/log/mosquitto.log
log_dest stdout
# For a first test only — switched to a password file in step 5
allow_anonymous true¿Quieres TLS, ACL o ajustes de bridge? El generador de mosquitto.conf crea un archivo válido a partir de un formulario, y la guía de instalación explica el modo solo local con más detalle.
3. Arráncalo con docker run
docker run -d --name mosquitto \
--restart unless-stopped \
-p 1883:1883 -p 9001:9001 \
-v "$PWD/mosquitto/config:/mosquitto/config" \
-v "$PWD/mosquitto/data:/mosquitto/data" \
-v "$PWD/mosquitto/log:/mosquitto/log" \
eclipse-mosquitto:2Fijar la etiqueta de versión mayor (eclipse-mosquitto:2) evita actualizaciones inesperadas. Revisa los logs con docker logs -f mosquitto; deberías ver Opening ipv4 listen socket on port 1883 y una línea de websockets para el 9001.
4. O usa Docker Compose
Para cualquier cosa más allá de una prueba rápida, un archivo Compose es más fácil de versionar:
services:
mosquitto:
image: eclipse-mosquitto:2
container_name: mosquitto
restart: unless-stopped
ports:
- "1883:1883" # MQTT
- "9001:9001" # MQTT over WebSockets
volumes:
- ./mosquitto/config:/mosquitto/config
- ./mosquitto/data:/mosquitto/data
- ./mosquitto/log:/mosquitto/logdocker compose up -d
docker compose logs -f mosquittoLos demás servicios del mismo proyecto Compose (Node-RED, Home Assistant, tu aplicación) llegan al broker por el nombre del servicio: mqtt://mosquitto:1883. Publica en el host solo los puertos que realmente necesite algo fuera de Docker.
5. Añade un archivo de contraseñas con docker exec
El acceso anónimo vale para un minuto de pruebas, nunca para algo más largo. Crea un usuario con mosquitto_passwd, que viene incluido en la imagen:
# -c creates the file (overwrites it if it exists!) — use only for the first user
docker exec -it mosquitto mosquitto_passwd -c /mosquitto/config/passwd alice
# add more users without -c
docker exec -it mosquitto mosquitto_passwd /mosquitto/config/passwd bobDespués cambia la configuración de acceso anónimo a autenticación por contraseña:
allow_anonymous false
password_file /mosquitto/config/passwddocker restart mosquittoLas ACL y TLS funcionan igual — los archivos van en el volumen de configuración. Consulta cómo proteger Mosquitto con contraseñas, ACL y TLS.
6. Prueba el contenedor
Desde el host (con los clientes de Mosquitto instalados):
mosquitto_sub -h localhost -p 1883 -u alice -P 'secret' -t 'demo/#' -v &
mosquitto_pub -h localhost -p 1883 -u alice -P 'secret' -t 'demo/hello' -m 'hi from docker'¿No tienes clientes en el host? Usa los que hay dentro del contenedor:
docker exec -it mosquitto mosquitto_sub -h localhost -u alice -P 'secret' -t 'demo/#' -vEl listener WebSocket del 9001 es el que usan los clientes en el navegador (ws://<host>:9001). Ten en cuenta que una página cargada por HTTPS solo puede abrir conexiones wss://, así que probar un broker local desde un cliente web alojado suele requerir TLS delante del puerto 9001 — más información en MQTT sobre WebSockets. Para ver cómo es una ida y vuelta que funciona en el navegador, prueba antes con un broker público:
Pruébalo en el cliente MQTT online
Solución de problemas del contenedor
| Síntoma | Causa | Solución |
|---|---|---|
| El log dice “Starting in local only mode” | La configuración no se montó o no define ningún listener | Revisa la ruta del volumen y que mosquitto.conf contenga listener 1883 |
| Connection refused desde el host | Puerto no publicado | Añade -p 1883:1883 (o la entrada ports:) y recrea el contenedor |
| “not authorised” / CONNACK 5 | Acceso anónimo desactivado, usuario o contraseña incorrectos | Vuelve a crear el usuario con mosquitto_passwd y luego docker restart mosquitto |
| “Unable to open log file” o errores de persistencia | El usuario del broker no puede escribir en la carpeta montada | Da permiso de escritura al UID 1883 en ./mosquitto/data y ./mosquitto/log |
| El contenedor se reinicia en bucle | Directiva no válida en la configuración | Lee las últimas líneas de docker logs mosquitto; ahí se indica la línea errónea |
Para otros códigos CONNACK, la referencia de códigos de motivo MQTT y la guía de errores de conexión explican lo que te está diciendo el broker.
Actualizar la imagen
Como la configuración, los datos y los logs viven en el host, actualizar consiste simplemente en descargar una imagen más nueva y recrear el contenedor. Los mensajes retenidos y las sesiones persistentes sobreviven mientras se conserve el volumen data:
docker compose pull mosquitto
docker compose up -d mosquitto
docker compose logs --tail 20 mosquittoCon docker run a secas, descarga la imagen, haz docker rm -f mosquitto y vuelve a ejecutar el mismo comando docker run. Guardar ese comando en un pequeño script de shell (o pasarte a Compose) te ahorra volver a escribir los flags de los volúmenes.
Consejos para producción
- Fija una etiqueta de imagen exacta y actualiza de forma deliberada; lee el changelog de Mosquitto antes de las actualizaciones mayores.
- Mantén
dataen un volumen; si no, los mensajes retenidos y las sesiones persistentes desaparecen al recrear el contenedor. - Pon TLS en el 8883 (y en el listener WebSocket) antes de exponer nada a internet — consulta los puertos MQTT para ver las convenciones.
- Para depurar, lee
docker logs mosquittoen lugar de ejecutarmosquitto -vcondocker exec— eso arranca un segundo broker dentro del contenedor y falla con “address already in use”.
Preguntas frecuentes
¿Por qué no puedo conectarme al contenedor Docker de Mosquitto desde mi host?
Sin un mosquitto.conf montado que defina un listener, Mosquitto 2.x funciona en modo solo local y solo acepta conexiones desde dentro del contenedor. Monta una configuración con listener 1883 y un ajuste de autenticación, y publica el puerto con -p 1883:1883.
¿Cómo añado un usuario a Mosquitto ejecutándose en Docker?
Ejecuta mosquitto_passwd dentro del contenedor con docker exec, escribiendo en un archivo de contraseñas de la carpeta de configuración montada, y reinicia el contenedor para que el broker vuelva a cargar el archivo.
¿Qué puertos usa la imagen eclipse-mosquitto?
Los listeners que configures. Por convención, el 1883 es MQTT sin cifrar sobre TCP, el 8883 es MQTT sobre TLS y el 9001 es MQTT sobre WebSockets. Cada uno debe definirse en mosquitto.conf y publicarse con Docker.