This documentation is part of the "Projects with Books" initiative at zenOSmosis.
The source code for this project is available on GitHub.
Getting Started
Relevant source files
Purpose and Scope
This page provides a step-by-step guide for deploying the Docker MQTT Mosquitto Cloudflare Tunnel system for the first time. It covers the complete workflow from initial Cloudflare configuration through container deployment and verification.
For detailed information about specific aspects of the setup:
Setup Overview
The system deployment consists of four primary phases:
- Cloudflare Tunnel Creation : Create and configure a tunnel in the Cloudflare Zero Trust dashboard
- Token Extraction : Obtain the
CLOUDFLARE_TUNNEL_TOKENfrom Cloudflare - Local Configuration : Create a
.envfile with the tunnel token - Container Deployment : Start the
mosquittoandcloudflaredservices using Docker Compose
Setup Workflow
Diagram: Complete Setup Process
Sources : README.md:23-73
Configuration File Relationships
Diagram: Configuration Files and Service Dependencies
Sources : docker-compose.yml:1-18 .env.sample:1-3 README.md:50-52
Quick Start Steps
Step 1: Cloudflare Tunnel Setup
Navigate to the Cloudflare Zero Trust dashboard and create a new tunnel:
- Access Zero Trust → Networks → Tunnels
- Click Create a tunnel
- Select Cloudflared as the tunnel type
- Provide a tunnel name (e.g.,
mqtt-tunnel) - On the connector installation screen, select Docker as the environment
- Copy the token from the provided Docker command
Important : Do not execute the Docker command shown in the Cloudflare dashboard. This repository provides its own Docker Compose configuration that supersedes that command.
Sources : README.md:27-54
Step 2: Public Hostname Configuration
Configure the public hostname that will route traffic to the MQTT broker:
| Configuration Field | Value | Description |
|---|---|---|
| Public hostname | your-subdomain.yourdomain.com | The public URL clients will connect to |
| Service Type | HTTP | Protocol type for the tunnel |
| Service URL | mosquitto:9001 | Internal Docker service reference |
The service URL mosquitto:9001 uses Docker's internal DNS resolution to route traffic to the mosquitto container defined in docker-compose.yml:4-9 on port 9001 (WebSocket listener).
Sources : README.md:55-66 docker-compose.yml:4-9
Step 3: Environment Configuration
Create a .env file in the repository root directory:
Edit .env and set the CLOUDFLARE_TUNNEL_TOKEN variable with the token obtained from Step 1:
CLOUDFLARE_TUNNEL_TOKEN=your_actual_token_here
The .env file is excluded from version control to prevent accidental token exposure.
Sources : .env.sample:1-3 README.md51
Step 4: Container Deployment
Deploy both services using Docker Compose:
This command:
- Pulls the
eclipse-mosquitto:latestimage (if not cached) - Pulls the
cloudflare/cloudflared:latestimage (if not cached) - Starts the
mosquittoservice with mounted configuration from docker-compose.yml:7-8 - Starts the
cloudflaredservice with the tunnel token from docker-compose.yml:16-17
Add the -d flag to run in detached mode:
Sources : README.md:68-72 docker-compose.yml:1-18
Verification
After deployment, verify both containers are running:
Expected output should show two containers:
| CONTAINER ID | IMAGE | COMMAND | STATUS | PORTS | NAMES |
|---|---|---|---|---|---|
<id> | eclipse-mosquitto:latest | /docker-entrypoint... | Up X seconds | 1883/tcp, 9001/tcp | mosquitto |
<id> | cloudflare/cloudflared:latest | tunnel --no-autoupdate... | Up X seconds | cloudflared |
Container Logs
Check the cloudflared container logs to verify tunnel establishment:
Successful output includes lines indicating the tunnel has been registered and connected to Cloudflare's network.
Check the mosquitto container logs to verify broker initialization:
Expected output shows listener initialization on ports 1883 and 9001.
Sources : docker-compose.yml:4-9 docker-compose.yml:11-17
Service Architecture During Startup
Diagram: Container Initialization Sequence
Sources : docker-compose.yml:1-18 README.md:68-72
Post-Deployment
Once both containers are running and the tunnel is established:
- External MQTT clients can connect to the public hostname configured in Step 2
- Traffic routes through Cloudflare's network to the
cloudflaredcontainer - The
cloudflaredcontainer proxies traffic tomosquitto:9001 - The
mosquittobroker handles MQTT connections on the WebSocket listener
Initial Connection Test
Test the public endpoint using an MQTT client. Cloudflare Tunnel typically uses port 443 (HTTPS) for the public endpoint, which is proxied to the internal mosquitto:9001 WebSocket listener.
Sources : README.md:15-20
Stopping the System
To stop both containers:
This command stops and removes both containers. The mosquitto.conf configuration file and .env file remain intact for the next startup. The docker-compose.yml9 restart: unless-stopped policy ensures containers restart automatically unless explicitly stopped.
Sources : docker-compose.yml:1-18
Next Steps
For detailed configuration and advanced topics:
Common Initial Setup Issues
| Issue | Symptom | Resolution |
|---|---|---|
| Missing .env file | cloudflared fails to start with authentication error | Create .env file from .env.sample:1-3 template and add valid token |
| Invalid tunnel token | cloudflared logs show authentication failure | Verify token in Cloudflare dashboard and update .env file |
| Port conflicts | Container fails to start with port binding error | Check if ports 1883 or 9001 are already in use on the host |
| Tunnel not found | cloudflared reports tunnel does not exist | Ensure tunnel was created in Cloudflare dashboard and token matches |
| Public hostname not configured | Clients cannot connect | Configure public hostname in Cloudflare dashboard as described in Step 2 |
| Volume mount errors | mosquitto fails to load configuration | Verify mosquitto.conf exists in repository root as defined in docker-compose.yml8 |
For comprehensive troubleshooting, see Troubleshooting.
Sources : README.md:23-73 docker-compose.yml:1-18 .env.sample:1-3