This documentation is part of the "Projects with Books" initiative at zenOSmosis.
The source code for this project is available on GitHub.
Deployment
Relevant source files
This document provides instructions for deploying the Docker MQTT Mosquitto Cloudflare Tunnel system using Docker Compose. It covers starting services, verifying successful deployment, managing service lifecycle, and troubleshooting deployment issues.
For configuration setup before deployment, see Environment Variables and Cloudflare Tunnel Configuration. For production deployment considerations, see Production Considerations.
Prerequisites Verification
Before deploying, ensure the following are in place:
| Requirement | Verification Command | Expected Result |
|---|---|---|
| Docker Engine | docker --version | Docker version 20.x or higher |
| Docker Compose | docker compose version | Docker Compose version 2.x or higher |
.env file | test -f .env && echo "exists" | "exists" |
CLOUDFLARE_TUNNEL_TOKEN | grep CLOUDFLARE_TUNNEL_TOKEN .env | Non-empty token value |
docker-compose.yml | test -f docker-compose.yml && echo "exists" | "exists" |
mosquitto.conf | test -f mosquitto.conf && echo "exists" | "exists" |
Sources: README.md51 docker-compose.yml:1-18 mosquitto.conf:1-6
Starting Services
Basic Deployment
The primary deployment command starts both the mosquitto and cloudflared services as defined in docker-compose.yml:1-18:
This command runs in the foreground, displaying logs from both containers in real-time. Press Ctrl+C to stop the services.
Sources: README.md:70-72
Detached Mode
For production deployments, run services in detached mode to release the terminal:
The -d flag starts containers in the background. Services continue running after terminal closure due to the restart: unless-stopped policy defined in docker-compose.yml:9-15
Sources: docker-compose.yml:9-15
Deployment Process Flow
Sources: docker-compose.yml:1-18 README.md:70-72
Rebuild and Deploy
When configuration or code changes require rebuilding images:
This forces Docker to rebuild images before starting services. Note: This system uses pre-built images (eclipse-mosquitto:latest and cloudflare/cloudflared:latest), so rebuilding is typically unnecessary unless custom Dockerfiles are introduced.
Sources: docker-compose.yml:5-12
Verifying Deployment
Container Status Check
Verify both containers are running:
Expected output:
NAME IMAGE STATUS
cloudflared cloudflare/cloudflared:latest Up X seconds
mosquitto eclipse-mosquitto:latest Up X seconds
Both containers should show STATUS as "Up" with no restart loops.
Sources: docker-compose.yml:6-13
Service-Specific Verification
Sources: docker-compose.yml:4-18 mosquitto.conf:1-6
Viewing Logs
Monitor service logs to verify successful startup:
Expected Log Patterns
mosquitto container:
Opening ipv4 listen socket on port 1883- TCP listener startedOpening websockets listen socket on port 9001- WebSocket listener started
cloudflared container:
Connection registered- Tunnel authenticated with CloudflareStarted tunnel- Tunnel operational and routing traffic
Sources: docker-compose.yml:4-17 mosquitto.conf:1-6
Health Check Script
Implement a health check loop similar to the CI pipeline pattern:
This pattern is derived from the CI workflow health check implementation.
Sources: High-level diagram CI/CD Testing Pipeline, docker-compose.yml:6-13
Managing Service Lifecycle
Stopping Services
Stop all services gracefully:
This sends SIGTERM to containers, allowing clean shutdown. Containers are stopped but not removed.
Sources: docker-compose.yml:1-18
Stopping and Removing
Stop services and remove containers:
This removes containers and networks but preserves volumes and images. The restart: unless-stopped policy means services will not restart automatically after docker compose down.
Sources: docker-compose.yml:9-15
Restarting Services
Restart all services:
Restart specific service:
Sources: docker-compose.yml:4-11
Service Lifecycle States
Sources: docker-compose.yml:9-15
Updating Services
Pull latest images and restart:
Sources: docker-compose.yml:5-12
Deployment Modes Comparison
| Mode | Command | Use Case | Logs Visible | Terminal Blocked |
|---|---|---|---|---|
| Foreground | docker compose up | Development, debugging | Yes, real-time | Yes |
| Detached | docker compose up -d | Production, background services | No (use docker compose logs) | No |
| Force Recreate | docker compose up --force-recreate | Config changes not detected | Depends on flags | Depends on flags |
| Build & Start | docker compose up --build | Custom image changes | Depends on flags | Depends on flags |
Sources: README.md:70-72 docker-compose.yml:1-18
Container Runtime Environment
Environment Variable Injection
The cloudflared service receives CLOUDFLARE_TUNNEL_TOKEN from the .env file via docker-compose.yml:16-17:
Docker Compose reads .env automatically and injects the variable into the container environment, where it's consumed by docker-compose.yml14:
Sources: docker-compose.yml:13-17
Volume Mount Configuration
The mosquitto service mounts its configuration file as specified in docker-compose.yml:7-8:
This creates a read-only bind mount, allowing configuration changes without rebuilding the container. Restart the mosquitto service to apply configuration changes:
Sources: docker-compose.yml:7-8 mosquitto.conf:1-6
Network Architecture
Sources: docker-compose.yml:1-18 README.md62
Deployment Checklist
Use this checklist to verify successful deployment:
- Prerequisites verified (Docker, Docker Compose installed)
.envfile created withCLOUDFLARE_TUNNEL_TOKENdocker-compose.ymlpresent in working directorymosquitto.confpresent in working directory- Cloudflare Tunnel configured with public hostname
docker compose up -dexecuted without errorsdocker compose psshows both containers runningdocker compose logs mosquittoshows listener messagesdocker compose logs cloudflaredshows tunnel connection registered- MQTT client can connect via Cloudflare public hostname
- Messages publish and subscribe successfully
Sources: README.md:23-72 docker-compose.yml:1-18
Common Deployment Issues
Token Not Found
Symptom: cloudflared container exits immediately
Cause: CLOUDFLARE_TUNNEL_TOKEN not set in .env
Solution:
Sources: docker-compose.yml:16-17
Port Conflicts
Symptom: mosquitto fails to start with "address already in use"
Cause: Another process using ports 1883 or 9001
Solution:
Sources: mosquitto.conf:1-4
Configuration File Not Found
Symptom: mosquitto container restarts repeatedly
Cause: mosquitto.conf missing or incorrect path in volume mount
Solution:
Sources: docker-compose.yml:7-8
Tunnel Connection Failure
Symptom: cloudflared logs show connection errors
Cause: Invalid token or network connectivity issues
Solution:
- Verify token in Cloudflare Zero Trust dashboard
- Check network connectivity:
ping cloudflare.com - Review
cloudflaredlogs:docker compose logs cloudflared - Regenerate token if expired
Sources: docker-compose.yml:13-17
Post-Deployment Validation
After deployment, validate the complete system:
Sources: docker-compose.yml:1-18 README.md:60-66