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.

Overview

Loading…

Overview

Relevant source files

Purpose and Scope

This document provides a comprehensive introduction to the Docker MQTT Mosquitto with Cloudflare Tunnel system, explaining its architecture, components, and operational model. This system deploys a containerized Eclipse Mosquitto MQTT broker and securely exposes it to the internet via Cloudflare Tunnel, eliminating the need for publicly exposed ports or inbound firewall rules.

For detailed architectural diagrams and component interactions, see System Architecture. For security principles and Zero Trust implementation details, see Security Model. For step-by-step deployment instructions, see Getting Started.

Sources: README.md:1-23


What is This System?

The Docker MQTT Mosquitto with Cloudflare Tunnel system is a production-ready deployment pattern that combines:

  • Eclipse Mosquitto : An open-source MQTT message broker that facilitates publish/subscribe messaging between IoT devices and applications
  • Cloudflare Tunnel : A secure tunneling service that exposes local services to the internet without opening inbound ports
  • Docker Compose : Container orchestration for reproducible, multi-container deployments

The system implements a Zero Trust security model where the MQTT broker has no internet-facing attack surface. All external traffic is routed through Cloudflare’s global edge network, which provides DDoS protection, SSL termination, and geographic distribution.

Sources: README.md:17-23


Key Features

The system provides the following capabilities:

FeatureDescriptionImplementation
Zero Trust AccessNo publicly exposed inbound ports on origin serverCloudflare Tunnel with outbound-only connections
Protocol SupportNative MQTT and WebSocket protocolsMosquitto listeners on ports 1883 and 9001
Container OrchestrationReproducible multi-container deploymentDocker Compose with service definitions
Automated TestingService health verification on every commitGitHub Actions CI workflow
DocumentationAuto-generated and published documentationGitHub Actions with DeepWiki integration
Secret ManagementSecure credential handling excluded from version control.env file with .gitignore protection
TLS EncryptionEnd-to-end encrypted connectionsCloudflare edge network SSL termination
Global DistributionLow-latency access from any geographic regionCloudflare’s global edge network

Sources: README.md:1-23 .github/workflows/ci.yml:1-41 .github/workflows/build-docs.yml:1-84


Core Components

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

Component Summary

ComponentContainer NamePurposeConfiguration
Mosquitto BrokermosquittoMQTT message broker handling pub/sub messagingmosquitto.conf:1-5 volume mount
Cloudflare ConnectorcloudflaredTunnel client establishing secure outbound connectionEnvironment variable CLOUDFLARE_TUNNEL_TOKEN
Docker ComposeN/AOrchestration layer managing container lifecycledocker-compose.yml:1-19

Supporting Configuration Files

FilePurposeVersion Control Status
mosquitto.confDefines MQTT listener ports and protocolsCommitted to repository
.envContains CLOUDFLARE_TUNNEL_TOKEN secretExcluded via .gitignore
.env.sampleTemplate showing required environment variablesCommitted to repository
.gitignorePrevents secret leakage to version controlCommitted to repository

Sources: docker-compose.yml:1-19 mosquitto.conf:1-5 .env.sample1 .gitignore:1-2


graph TB
    subgraph Internet["Internet / Public Network"]
Client["External MQTT Clients\n(IoT Devices, Applications)"]
end
    
    subgraph CF["Cloudflare Network"]
Edge["Cloudflare Edge\nTLS Termination\nPort 443"]
Tunnel["Cloudflare Tunnel Service"]
end
    
    subgraph DockerHost["Docker Host"]
Compose["docker-compose.yml\nServices Orchestration"]
subgraph Network["Docker Network (Bridge)"]
MosqContainer["Container: mosquitto\neclipse-mosquitto:latest\ncontainer_name: mosquitto"]
CFDContainer["Container: cloudflared\ncloudflare/cloudflared:latest\ncontainer_name: cloudflared"]
end
        
        MosqConf["mosquitto.conf\nVolume Mount\n/mosquitto/config/mosquitto.conf"]
EnvFile[".env\nCLOUDFLARE_TUNNEL_TOKEN"]
end
    
 
   Client -->|HTTPS/WSS Port 443| Edge
 
   Edge -->|Secure Tunnel| Tunnel
 
   Tunnel <-->|Outbound Connection Token Authentication| CFDContainer
    
 
   Compose -->|manages| MosqContainer
 
   Compose -->|manages| CFDContainer
    
 
   MosqConf -->|volumes: ./mosquitto.conf| MosqContainer
 
   EnvFile -->|environment: CLOUDFLARE_TUNNEL_TOKEN| CFDContainer
    
 
   CFDContainer -->|HTTP to mosquitto:9001| MosqContainer
    
 
   MosqContainer -->|listener 1883 protocol mqtt| ListenerMQTT["MQTT Protocol\nInternal Port 1883"]
MosqContainer -->|listener 9001 protocol websockets| ListenerWS["WebSocket Protocol\nInternal Port 9001"]

System Topology

The following diagram illustrates the complete system architecture, mapping high-level concepts to specific code entities and configuration elements:

Container and Network Topology

Key Code Entities:

Sources: docker-compose.yml:1-19 mosquitto.conf:1-5 README.md:64-67


sequenceDiagram
    participant Client as "External Client\n(MQTT/WebSocket)"
    participant CFEdge as "Cloudflare Edge\nPort 443 HTTPS"
    participant CFTunnel as "Cloudflare Tunnel\nInfrastructure"
    participant CloudflaredContainer as "Container: cloudflared\nCommand: tunnel run"
    participant DockerDNS as "Docker Internal DNS\nmosquitto:9001"
    participant MosquittoContainer as "Container: mosquitto\nPort 9001 Listener"
    
    Note over Client,MosquittoContainer: Initial Connection Phase
    CloudflaredContainer->>CFTunnel: Establish tunnel using\nCLOUDFLARE_TUNNEL_TOKEN
    CFTunnel-->>CloudflaredContainer: Tunnel authenticated and ready
    
    Note over Client,MosquittoContainer: Client CONNECT Request
    Client->>CFEdge: CONNECT to https://subdomain.domain:443
    CFEdge->>CFTunnel: Route via tunnel config\nPublic Hostname mapping
    CFTunnel->>CloudflaredContainer: Forward through secure tunnel
    CloudflaredContainer->>DockerDNS: Resolve "mosquitto:9001"
    DockerDNS-->>CloudflaredContainer: Return container IP
    CloudflaredContainer->>MosquittoContainer: HTTP request to port 9001\nprotocol websockets
    MosquittoContainer-->>CloudflaredContainer: WebSocket upgrade response
    CloudflaredContainer-->>CFTunnel: Return response
    CFTunnel-->>CFEdge: Return response
    CFEdge-->>Client: HTTPS/WSS connection established
    
    Note over Client,MosquittoContainer: Client PUBLISH Message
    Client->>CFEdge: PUBLISH to topic
    CFEdge->>CFTunnel: Forward
    CFTunnel->>CloudflaredContainer: Via tunnel
    CloudflaredContainer->>MosquittoContainer: HTTP POST to mosquitto:9001
    MosquittoContainer->>MosquittoContainer: Process message\nRoute to subscribers
    MosquittoContainer-->>CloudflaredContainer: PUBACK
    CloudflaredContainer-->>CFTunnel: Return
    CFTunnel-->>CFEdge: Return
    CFEdge-->>Client: PUBACK confirmation

Request Flow Architecture

This diagram traces a complete MQTT message flow from external client to broker, mapping each step to specific code entities and configuration elements:

End-to-End Message Flow

Key Code References in Flow:

  1. Tunnel Authentication : CLOUDFLARE_TUNNEL_TOKEN from docker-compose.yml:16-17 passed to cloudflared container
  2. Tunnel Command : tunnel run in docker-compose.yml13 establishes outbound connection
  3. DNS Resolution : Service name mosquitto defined in docker-compose.yml4 resolved by Docker’s internal DNS
  4. Port Configuration : 9001 listener defined in mosquitto.conf:4-5 handles WebSocket connections
  5. Protocol Setting : protocol websockets in mosquitto.conf5 enables WebSocket support
  6. Public Hostname : Configured in Cloudflare dashboard (Step 3 of README.md:57-72) maps public URL to internal mosquitto:9001

Sources: docker-compose.yml:1-19 mosquitto.conf:1-5 README.md:57-72


Deployment Model

The system uses a two-phase deployment model that separates cloud configuration from local execution:

Phase 1: Cloud Configuration (One-Time Setup)

StepActionOutcome
1Create Cloudflare Tunnel via Zero Trust dashboardGenerates unique tunnel identifier
2Configure tunnel connector type (Cloudflared)Provides Docker deployment command
3Copy CLOUDFLARE_TUNNEL_TOKEN from generated commandToken for authenticating local connector
4Configure Public Hostname mappingMaps public URL to mosquitto:9001 internal address

Sources: README.md:29-72

Phase 2: Local Deployment (Repeatable)

StepCommand/ActionFile Reference
1Create .env file from .env.sample template.env.sample1
2Add CLOUDFLARE_TUNNEL_TOKEN=<token> to .envdocker-compose.yml:16-17
3Verify .env excluded from Git.gitignore1
4Run docker compose updocker-compose.yml1

Sources: README.md:53-78 .env.sample1 .gitignore:1-2


Security Architecture

The system implements defense-in-depth security through multiple layers:

Security Layers

Key Security Implementations:

  1. No Inbound Ports : docker-compose.yml:1-19 defines no ports: sections, preventing host exposure
  2. Outbound-Only Connection : tunnel run command in docker-compose.yml13 establishes connection from origin to Cloudflare
  3. Secret Exclusion : .env pattern in .gitignore1 prevents accidental token commits
  4. Anonymous Access : Currently configured as allow_anonymous true in mosquitto.conf3 - see Authentication and Access Control for implications

For comprehensive security documentation, see Security Model.

Sources: docker-compose.yml:1-19 mosquitto.conf:1-5 .gitignore:1-2


Advanced Features

The repository includes an alternative branch with additional security features:

Protected Branch Features

The protected-no-wildcard branch implements:

FeatureImplementationDocumentation
Wildcard Topic RestrictionsACL file restricting cross-user wildcard subscriptionsREADME.md9
Encrypted Retained Messagesgocryptfs filesystem encryptionREADME.md10
Auto-Save PersistenceAutomatic message persistence after every publishREADME.md11

See Protected Branch Features for detailed documentation.

Sources: README.md:7-13


CI/CD Integration

The system includes automated quality assurance through GitHub Actions:

Continuous Integration Workflow

The .github/workflows/ci.yml:1-41 workflow performs:

  1. Service Provisioning : Starts mosquitto container via docker-compose up -d mosquitto
  2. Health Check Loop : Polls container status up to 10 times with 10-second intervals
  3. Verification : Ensures docker ps | grep mosquitto | grep "Up" succeeds
  4. Cleanup : Executes docker-compose down regardless of test outcome

Documentation Pipeline

The .github/workflows/build-docs.yml:1-84 workflow:

  1. Generates documentation using DeepWiki integration
  2. Builds mdBook static site
  3. Deploys to GitHub Pages on weekly schedule or manual trigger

For complete CI/CD documentation, see CI/CD and Automation.

Sources: .github/workflows/ci.yml:1-41 .github/workflows/build-docs.yml:1-84


Quick Start Reference

To deploy this system:

  1. Prerequisites : Docker, Docker Compose, Cloudflare account (see Prerequisites)
  2. Cloudflare Setup : Create tunnel and obtain token (see Cloudflare Tunnel Setup)
  3. Local Configuration : Create .env file with token (see Local Configuration)
  4. Deployment : Run docker compose up (see Deployment)

Your MQTT broker will be accessible at https://<subdomain>.<domain>:443 as configured in the Cloudflare Public Hostname settings.

Important : The URL mosquitto:9001 referenced in README.md64 is internal to Docker and resolved via the service name in docker-compose.yml4 The public URL is configured separately in the Cloudflare dashboard and uses HTTPS on port 443, not HTTP on port 9001.

For complete deployment instructions, see Getting Started.

Sources: README.md:25-84 docker-compose.yml:1-19

Dismiss

Refresh this wiki

Enter email to refresh