This documentation is part of the "Projects with Books" initiative at zenOSmosis.
The source code for this project is available on GitHub.
Local Development Setup
Relevant source files
Purpose and Scope
This document provides a guide for developers setting up a local development environment for the Docker MQTT Mosquitto Cloudflare Tunnel system. It covers repository cloning, file structure, configuration management, and running the system locally for development purposes.
For information about system prerequisites (Docker installation, Cloudflare account requirements), see Prerequisites. For detailed Cloudflare Tunnel setup, see Cloudflare Tunnel Configuration. For in-depth version control practices and .gitignore policies, see Version Control Practices. For production deployment procedures, see Deployment.
Local File Structure
The repository contains version-controlled configuration files and excludes sensitive credentials and runtime data from version control.
graph TB
subgraph "Version Controlled"
dockercompose["docker-compose.yml\nService Orchestration"]
mosquittoconf["mosquitto.conf\nBroker Configuration"]
envsample[".env.sample\nEnvironment Template"]
gitignore[".gitignore\nExclusion Rules"]
end
subgraph "Excluded from Version Control"
envfile[".env\nActual Secrets"]
datadir["data/*\nRuntime Data"]
end
gitignore -->|Excludes| envfile
gitignore -->|Excludes| datadir
envsample -.->|Template for| envfile
dockercompose -->|References ${CLOUDFLARE_TUNNEL_TOKEN}| envfile
mosquittoconf -.->|May write to| datadir
Version-Controlled vs. Excluded Files
Sources : .gitignore:1-3 .env.sample:1-3 docker-compose.yml:1-18
The .gitignore file explicitly excludes two items from version control:
| Excluded Item | Purpose | Reason for Exclusion |
|---|---|---|
.env | Contains CLOUDFLARE_TUNNEL_TOKEN | Sensitive authentication credential |
data/* | Runtime data generated by Mosquitto | Instance-specific, not portable |
Sources : .gitignore:1-2
Development Workflow
Initial Repository Setup
Sources : .env.sample:1-3 .gitignore:1-2 docker-compose.yml:14-17
Step-by-Step Setup Process
1. Clone the Repository
2. Create Local Environment File
The .env.sample file serves as a template for the actual .env file:
Create your local .env file:
The newly created .env file is automatically excluded from version control by the .gitignore configuration at .gitignore1
Sources : .env.sample:1-3 .gitignore1
3. Obtain Cloudflare Tunnel Token
The CLOUDFLARE_TUNNEL_TOKEN must be obtained from the Cloudflare Zero Trust dashboard. This token authenticates the cloudflared service with Cloudflare's infrastructure. For detailed instructions on creating a tunnel and obtaining the token, see Cloudflare Tunnel Configuration.
Sources : .env.sample1 docker-compose.yml:14-17
4. Configure Environment Variables
Edit the .env file and replace the placeholder value:
CLOUDFLARE_TUNNEL_TOKEN=your_actual_token_here
The docker-compose.yml file references this environment variable at docker-compose.yml14 and docker-compose.yml17 passing it to the cloudflared container.
Sources : .env.sample1 docker-compose.yml:14-17
graph LR
subgraph "Configuration Files"
dockercompose["docker-compose.yml"]
mosquittoconf["mosquitto.conf"]
envfile[".env"]
end
subgraph "Docker Services"
mosquitto["mosquitto\nContainer"]
cloudflared["cloudflared\nContainer"]
end
dockercompose -->|Orchestrates both services| mosquitto
dockercompose -->|Orchestrates both services| cloudflared
mosquittoconf -->|Volume mount at /mosquitto/config/mosquitto.conf| mosquitto
envfile -->|Environment variable CLOUDFLARE_TUNNEL_TOKEN| cloudflared
Configuration File Mapping
The following diagram maps each configuration file to its purpose and the service that consumes it:
Sources : docker-compose.yml:1-18
Configuration File Details
| File | Purpose | Consumer | Mount/Injection Method |
|---|---|---|---|
docker-compose.yml | Service orchestration | Docker Compose | N/A |
mosquitto.conf | Broker settings | mosquitto container | Volume mount at line 8 |
.env | Secrets and tokens | cloudflared container | Environment variable at lines 16-17 |
The docker-compose.yml file defines the volume mount for mosquitto.conf at docker-compose.yml8:
The .env file's CLOUDFLARE_TUNNEL_TOKEN is injected into the cloudflared service as an environment variable at docker-compose.yml:16-17:
Sources : docker-compose.yml:7-9 docker-compose.yml:16-17
Running the System Locally
Service Startup
Start both services in detached mode:
This command:
- Reads
docker-compose.ymlfor service definitions - Loads environment variables from
.env - Starts the
mosquittocontainer with the volume-mountedmosquitto.conf - Starts the
cloudflaredcontainer with theCLOUDFLARE_TUNNEL_TOKENenvironment variable
Sources : docker-compose.yml:1-18
Service Definitions
The docker-compose.yml defines two services:
mosquitto Service
| Property | Value | Purpose |
|---|---|---|
image | eclipse-mosquitto:latest | Official Mosquitto MQTT broker image |
container_name | mosquitto | Fixed container name for service discovery |
volumes | ./mosquitto.conf:/mosquitto/config/mosquitto.conf | Mounts local configuration into container |
restart | unless-stopped | Automatic restart policy |
cloudflared Service
| Property | Value | Purpose |
|---|---|---|
image | cloudflare/cloudflared:latest | Official Cloudflare Tunnel client image |
container_name | cloudflared | Fixed container name for service discovery |
command | tunnel --no-autoupdate run --token ${CLOUDFLARE_TUNNEL_TOKEN} | Tunnel client startup with token substitution |
restart | unless-stopped | Automatic restart policy |
environment | CLOUDFLARE_TUNNEL_TOKEN | Passes token from .env file |
Sources : docker-compose.yml:4-17
Local Data Directory
The data/ directory is excluded from version control at .gitignore2 This directory may be used by Mosquitto for persistent storage of retained messages or other runtime data. The directory is instance-specific and should not be committed to version control.
For encrypted retained message storage available in the protected-no-wildcard branch, see Encrypted Retained Messages.
Sources : .gitignore2
Development vs. Production Differences
Local Development Configuration
In local development:
- The
.envfile is manually created and maintained by each developer - The
data/directory contains local runtime state - Services restart automatically via
unless-stoppedpolicy at docker-compose.yml9 and docker-compose.yml15 - Configuration changes require service restart
Version Control Exclusions
The .gitignore configuration ensures that sensitive and instance-specific files never enter version control:
| Pattern | Matches | Reason |
|---|---|---|
.env | Exact file match | Contains CLOUDFLARE_TUNNEL_TOKEN secret |
data/* | All files in data/ directory | Instance-specific runtime data |
Sources : .gitignore:1-2
Verifying Local Setup
After starting services, verify that both containers are running:
Expected output should show both mosquitto and cloudflared containers with status "Up".
To view logs:
For detailed troubleshooting procedures, see Troubleshooting.
Sources : docker-compose.yml6 docker-compose.yml13
Making Configuration Changes
Modifying Mosquitto Configuration
To change Mosquitto settings:
- Edit
mosquitto.conflocally - Restart the
mosquittoservice:
The volume mount at docker-compose.yml8 ensures the local file is immediately reflected in the container.
Modifying Environment Variables
To change the Cloudflare tunnel token or add new environment variables:
- Edit
.envfile - Restart the
cloudflaredservice:
Environment variables are loaded at container startup and referenced at docker-compose.yml:16-17
Sources : docker-compose.yml:7-9 docker-compose.yml:16-17
Summary
Local development setup requires:
- Repository cloning from GitHub
- Environment file creation by copying
.env.sampleto.env - Token acquisition from Cloudflare Dashboard
- Service startup via
docker-compose up -d
The system maintains a clear separation between version-controlled configuration (.env.sample, docker-compose.yml, mosquitto.conf) and excluded sensitive/runtime data (.env, data/*). This separation ensures secure credential management while maintaining reproducible configuration across development environments.
Sources : .gitignore:1-2 .env.sample:1-3 docker-compose.yml:1-18