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.

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:

  1. Cloudflare Tunnel Creation : Create and configure a tunnel in the Cloudflare Zero Trust dashboard
  2. Token Extraction : Obtain the CLOUDFLARE_TUNNEL_TOKEN from Cloudflare
  3. Local Configuration : Create a .env file with the tunnel token
  4. Container Deployment : Start the mosquitto and cloudflared services 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:

  1. Access Zero TrustNetworksTunnels
  2. Click Create a tunnel
  3. Select Cloudflared as the tunnel type
  4. Provide a tunnel name (e.g., mqtt-tunnel)
  5. On the connector installation screen, select Docker as the environment
  6. 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 FieldValueDescription
Public hostnameyour-subdomain.yourdomain.comThe public URL clients will connect to
Service TypeHTTPProtocol type for the tunnel
Service URLmosquitto:9001Internal 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:

  1. Pulls the eclipse-mosquitto:latest image (if not cached)
  2. Pulls the cloudflare/cloudflared:latest image (if not cached)
  3. Starts the mosquitto service with mounted configuration from docker-compose.yml:7-8
  4. Starts the cloudflared service 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 IDIMAGECOMMANDSTATUSPORTSNAMES
<id>eclipse-mosquitto:latest/docker-entrypoint...Up X seconds1883/tcp, 9001/tcpmosquitto
<id>cloudflare/cloudflared:latesttunnel --no-autoupdate...Up X secondscloudflared

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:

  1. External MQTT clients can connect to the public hostname configured in Step 2
  2. Traffic routes through Cloudflare's network to the cloudflared container
  3. The cloudflared container proxies traffic to mosquitto:9001
  4. The mosquitto broker 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

IssueSymptomResolution
Missing .env filecloudflared fails to start with authentication errorCreate .env file from .env.sample:1-3 template and add valid token
Invalid tunnel tokencloudflared logs show authentication failureVerify token in Cloudflare dashboard and update .env file
Port conflictsContainer fails to start with port binding errorCheck if ports 1883 or 9001 are already in use on the host
Tunnel not foundcloudflared reports tunnel does not existEnsure tunnel was created in Cloudflare dashboard and token matches
Public hostname not configuredClients cannot connectConfigure public hostname in Cloudflare dashboard as described in Step 2
Volume mount errorsmosquitto fails to load configurationVerify 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