Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

GitHub

This documentation is part of the "Projects with Books" initiative at zenOSmosis.

The source code for this project is available on GitHub.

Components

Relevant source files

This document provides detailed technical documentation of the major components that constitute the Docker MQTT Mosquitto Cloudflare Tunnel system. Each component is examined in terms of its Docker service configuration, runtime behavior, and integration with other system components.

For architectural overview and how these components interact at a system level, see System Architecture. For deployment instructions, see Deployment. For advanced branch-specific features like ACLs and encryption, see Advanced Topics.

Component Overview

The system consists of three primary components orchestrated by Docker Compose:

ComponentContainer NameImagePrimary Function
Mosquitto MQTT Brokermosquittoeclipse-mosquitto:latestMQTT message broker providing pub/sub messaging
Cloudflared Tunnel Clientcloudflaredcloudflare/cloudflare:latestSecure tunnel client connecting broker to Cloudflare network
Docker ComposeN/AN/AService orchestration and configuration management

Component Interaction Diagram

Sources : docker-compose.yml, README.md, mosquitto.conf

Mosquitto MQTT Broker

The Mosquitto service provides MQTT protocol brokering functionality. This component runs the Eclipse Mosquitto broker inside a Docker container, configured for WebSocket and TCP connections with anonymous access enabled.

Service Definition

The Mosquitto service is defined in docker-compose.yml:4-9 with the following configuration:

PropertyValuePurpose
imageeclipse-mosquitto:latestOfficial Mosquitto Docker image
container_namemosquittoFixed container name for internal DNS resolution
volumes./mosquitto.conf:/mosquitto/config/mosquitto.confMounts configuration file into container
restartunless-stoppedAutomatic restart policy for service reliability

The container name mosquitto is critical as it serves as the internal DNS hostname that cloudflared uses to proxy traffic (referenced in Cloudflare tunnel configuration as mosquitto:9001).

Sources : docker-compose.yml:4-9, README.md:62

graph LR
    subgraph MosquittoContainer["mosquitto Container"]
subgraph ListenerConfig["mosquitto.conf Configuration"]
Listener1["listener 1883\nprotocol mqtt"]
Listener2["listener 9001\nprotocol websockets"]
end
        
        subgraph BrokerCore["Mosquitto Broker Process"]
MQTTEngine["MQTT Protocol Engine"]
end
        
 
       Listener1 -->|standard TCP/IP| MQTTEngine
 
       Listener2 -->|WebSocket framing| MQTTEngine
    end
    
    subgraph ExternalAccess["External Access Paths"]
TCPClient["TCP MQTT Clients\n(port 1883)"]
WSClient["WebSocket Clients\n(via cloudflared proxy)"]
end
    
 
   TCPClient -.->|internal network only not exposed via tunnel| Listener1
 
   WSClient -->|proxied through cloudflared:mosquitto:9001| Listener2

MQTT Listeners

The Mosquitto broker is configured with two distinct listeners, each serving different client connection patterns:

Listener Configuration Overview

Sources : mosquitto.conf, README.md:62, docker-compose.yml:4-9

Standard TCP Listener (Port 1883)

Configured in mosquitto.conf as:

listener 1883
protocol mqtt

This listener provides standard MQTT-over-TCP connectivity on the default MQTT port. It is accessible within the Docker internal network but is not exposed through the Cloudflare tunnel in the default configuration.

Use cases :

  • Direct connections from other Docker containers on the same network
  • Internal service-to-service MQTT communication
  • Local development and testing

WebSocket Listener (Port 9001)

Configured in mosquitto.conf as:

listener 9001
protocol websockets

This listener provides MQTT-over-WebSocket connectivity, which is the primary listener exposed through the Cloudflare tunnel. The cloudflared service proxies external traffic to mosquitto:9001 as configured in the Cloudflare Zero Trust dashboard.

Use cases :

  • Browser-based MQTT clients
  • Web applications requiring MQTT connectivity
  • Clients behind restrictive firewalls that block non-HTTP protocols
  • The primary access method for external clients via Cloudflare tunnel

Sources : mosquitto.conf, README.md:55-66

Anonymous Access

The Mosquitto broker is configured with anonymous access enabled, meaning no authentication is required to connect or publish/subscribe to topics.

Configuration :

allow_anonymous true

This setting in mosquitto.conf permits any client that can reach the broker to perform MQTT operations without credentials.

Security implications :

AspectImplication
AuthenticationNone - all clients are accepted
AuthorizationNo topic-level access control in main branch
Trust modelBroker trusts all traffic from cloudflared
Network securitySecurity relies entirely on Cloudflare tunnel and network isolation

The security model assumes that network-level access control (via Cloudflare tunnel) provides sufficient protection. For environments requiring topic-level access control, see Topic Access Control (ACL)) which documents the protected-no-wildcard branch implementation.

Sources : mosquitto.conf, README.md:5-11

Cloudflared Tunnel Service

The cloudflared service establishes a secure, outbound-only connection to Cloudflare's network, enabling external MQTT clients to reach the internal Mosquitto broker without exposing inbound ports on the host.

Service Definition

The cloudflared service is defined in docker-compose.yml:11-17:

PropertyValuePurpose
imagecloudflare/cloudflared:latestOfficial Cloudflare tunnel client image
container_namecloudflaredFixed container name
commandtunnel --no-autoupdate run --token ${CLOUDFLARE_TUNNEL_TOKEN}Starts tunnel with authentication token
restartunless-stoppedAutomatic restart policy
environmentCLOUDFLARE_TUNNEL_TOKENPasses tunnel authentication token from .env file

Sources : docker-compose.yml:11-17

Tunnel Authentication and Establishment

Tunnel Connection Flow

Sources : docker-compose.yml:11-17, .env.sample, README.md:47-53

Command Line Arguments

The command directive in docker-compose.yml14 specifies:

tunnel --no-autoupdate run --token ${CLOUDFLARE_TUNNEL_TOKEN}
ArgumentPurpose
tunnelPrimary cloudflared operation mode
--no-autoupdateDisables automatic updates (container image updates handled via Docker)
runRuns the tunnel in persistent mode
--tokenAuthenticates with Cloudflare using provided token
${CLOUDFLARE_TUNNEL_TOKEN}Environment variable interpolation from .env file

The token is obtained during tunnel creation in the Cloudflare Zero Trust dashboard (see Cloudflare Tunnel Configuration) and stored in the .env file as documented in .env.sample

Sources : docker-compose.yml:14, .env.sample, README.md:47-53

Traffic Proxying

Once the tunnel is established, cloudflared proxies incoming traffic from Cloudflare's edge to the internal Mosquitto broker. The routing configuration is managed in the Cloudflare Zero Trust dashboard, not in local configuration files.

The public hostname configuration in Cloudflare maps to the service URL mosquitto:9001, where:

  • mosquitto resolves via Docker's internal DNS to the container with container_name: mosquitto
  • Port 9001 corresponds to the WebSocket listener configured in mosquitto.conf

Sources : README.md:55-66, docker-compose.yml

Docker Compose Orchestration

Docker Compose provides service orchestration, dependency management, and configuration binding for the system.

Service Orchestration Model

Docker Compose Component Relationships

Sources : docker-compose.yml

Network Configuration

Docker Compose creates a default bridge network for service communication. The network configuration is implicit (no explicit networks section in docker-compose.yml).

Network characteristics :

AspectBehavior
Network typeBridge network (default)
Network name{project_name}_default (typically docker-mqtt-mosquitto-cloudflare-tunnel_default)
DNS resolutionContainer names resolve to container IPs (mosquitto → container IP)
Inter-service communicationAll services can reach each other using container names
External connectivityServices can initiate outbound connections (used by cloudflared)

The internal DNS resolution is critical: when the Cloudflare tunnel configuration specifies mosquitto:9001, Docker's embedded DNS server resolves mosquitto to the IP address of the container with container_name: mosquitto.

Sources : docker-compose.yml, README.md:62

Volume Management

The Mosquitto service uses a bind mount to inject configuration:

Volume mapping details :

Source (Host)Target (Container)Mount TypePurpose
./mosquitto.conf/mosquitto/config/mosquitto.confBind mountProvides broker configuration at runtime

The configuration file is read by the Mosquitto broker on startup. Changes to mosquitto.conf require container restart to take effect:

No data persistence volumes are configured in the default setup. For persistent message storage, see Advanced Topics and the protected-no-wildcard branch documentation.

Sources : docker-compose.yml:7-8, mosquitto.conf

Environment Variable Injection

The cloudflared service receives environment variables via docker-compose.yml:16-17:

This syntax instructs Docker Compose to:

  1. Read CLOUDFLARE_TUNNEL_TOKEN from the .env file in the same directory
  2. Pass it as an environment variable to the cloudflared container
  3. Make it available for substitution in the command directive via ${CLOUDFLARE_TUNNEL_TOKEN}

The .env file is not version-controlled (excluded via .gitignore). Developers create it from .env.sample as documented in Environment Variables.

Sources : docker-compose.yml:16-17, .env.sample

Restart Policies

Both services use restart: unless-stopped:

Restart behavior :

ScenarioBehavior
Container exits with errorAutomatically restarts
Container exits cleanly (exit 0)Automatically restarts
Docker daemon restartsContainers restart automatically
Manual docker stopContainer remains stopped after Docker daemon restart
System rebootContainers restart if Docker daemon starts automatically

This policy ensures service availability while allowing manual control via docker compose down or docker stop.

Sources : docker-compose.yml:9,15

Service Lifecycle Management

Common Docker Compose Commands :

CommandEffect
docker compose upCreates and starts both services in foreground
docker compose up -dCreates and starts both services in background (detached)
docker compose downStops and removes containers, networks
docker compose restartRestarts all services
docker compose restart mosquittoRestarts only Mosquitto service
docker compose logsShows logs from all services
docker compose logs -f cloudflaredFollows logs from cloudflared service

For detailed deployment procedures, see Deployment.

Sources : docker-compose.yml, README.md:68-72