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.

Deployment

Loading…

Deployment

Relevant source files

This page covers the process of deploying the Docker MQTT Mosquitto with Cloudflare Tunnel system using Docker Compose. It assumes you have completed the Cloudflare Tunnel setup (see Cloudflare Tunnel Setup) and local configuration (see Local Configuration). For production deployment considerations, see Production Deployment Considerations. For detailed troubleshooting, see Troubleshooting.

Starting the System

With the .env file configured and mosquitto.conf in place, deploy the system using Docker Compose:

This command starts both the mosquitto and cloudflared containers as defined in docker-compose.yml:3-17 The command runs in the foreground, displaying logs from both containers in real-time.

Deployment Modes

CommandBehaviorUse Case
docker compose upForeground mode with logsDevelopment, debugging, initial testing
docker compose up -dDetached mode (background)Production, long-running deployments
docker compose up --buildRebuild images before startingAfter configuration changes requiring rebuild

Sources: README.md:74-78 docker-compose.yml:1-18


Deployment Sequence

The following sequence diagram shows the complete deployment lifecycle from command execution to operational state:

Deployment Initialization Flow

sequenceDiagram
    participant User
    participant DockerCompose as "docker-compose\n(Orchestrator)"
    participant DockerEngine as "Docker Engine"
    participant MosqContainer as "mosquitto\n(Container)"
    participant CFDContainer as "cloudflared\n(Container)"
    participant CFTunnel as "Cloudflare Tunnel\n(Service)"
    participant MosqProcess as "Mosquitto Process\n(MQTT Broker)"
    
    User->>DockerCompose: docker compose up
    DockerCompose->>DockerEngine: Parse docker-compose.yml
    DockerEngine->>DockerEngine: Create bridge network
    
    Note over DockerEngine,MosqContainer: Start mosquitto service
    DockerEngine->>MosqContainer: Pull eclipse-mosquitto:latest
    DockerEngine->>MosqContainer: Create container
    DockerEngine->>MosqContainer: Mount ./mosquitto.conf to /mosquitto/config/
    MosqContainer->>MosqProcess: Start mosquitto daemon
    MosqProcess->>MosqProcess: Read /mosquitto/config/mosquitto.conf
    MosqProcess->>MosqProcess: Bind listener on port 1883
    MosqProcess->>MosqProcess: Bind listener on port 9001 (websockets)
    MosqProcess-->>DockerEngine: Container running
    
    Note over DockerEngine,CFDContainer: Start cloudflared service
    DockerEngine->>CFDContainer: Pull cloudflare/cloudflared:latest
    DockerEngine->>CFDContainer: Create container
    DockerEngine->>CFDContainer: Inject CLOUDFLARE_TUNNEL_TOKEN from .env
    CFDContainer->>CFDContainer: Execute: tunnel --no-autoupdate run --token
    CFDContainer->>CFTunnel: Establish tunnel connection
    CFTunnel-->>CFDContainer: Tunnel established
    CFDContainer->>CFDContainer: Resolve mosquitto via DNS
    CFDContainer-->>DockerEngine: Container running
    
    DockerEngine-->>DockerCompose: Both services started
    DockerCompose-->>User: Display container logs
    
    Note over User,MosqProcess: System operational

Sources: docker-compose.yml:1-18 README.md:74-78


Container Startup Behavior

Each service defined in docker-compose.yml:3-17 has specific startup characteristics:

mosquitto Container

The mosquitto container starts with the following configuration:

Upon startup, the Mosquitto process reads the mounted configuration file and initializes two listeners as specified in mosquitto.conf.

cloudflared Container

The cloudflared container starts with the following configuration:

The --no-autoupdate flag prevents the container from attempting to update itself, maintaining version consistency with the Docker image.

Sources: docker-compose.yml:3-18


Verifying Deployment

After starting the system, verify that both containers are running and the tunnel is operational.

Container Status Verification Flow

graph TD
    Start["Deployment Started"]
CheckContainers["docker compose ps"]
VerifyStatus{"Both containers\nSTATUS=Up?"}
CheckLogs["docker compose logs"]
VerifyMosquitto{"Mosquitto logs show\nlisteners bound?"}
VerifyCloudflared{"Cloudflared logs show\ntunnel registered?"}
TestConnection["Test MQTT connection\nto public hostname"]
Success["Deployment Verified"]
Failure["Deployment Failed"]
Start --> CheckContainers
 
   CheckContainers --> VerifyStatus
 
   VerifyStatus -->|No| Failure
 
   VerifyStatus -->|Yes| CheckLogs
 
   CheckLogs --> VerifyMosquitto
 
   VerifyMosquitto -->|No| Failure
 
   VerifyMosquitto -->|Yes| VerifyCloudflared
 
   VerifyCloudflared -->|No| Failure
 
   VerifyCloudflared -->|Yes| TestConnection
 
   TestConnection -->|Connection successful| Success
 
   TestConnection -->|Connection failed| Failure

Sources: README.md:82-84


Check Container Status

List running containers and their status:

Expected output should show both containers with STATUS as Up:

NAMEIMAGESTATUSPORTS
mosquittoeclipse-mosquitto:latestUp X minutes1883/tcp, 9001/tcp
cloudflaredcloudflare/cloudflared:latestUp X minutes

Sources: docker-compose.yml:4-17


View Container Logs

View logs from all services:

View logs from a specific service:

Follow logs in real-time:

Expected Mosquitto Logs

Successful Mosquitto startup logs include:

mosquitto    | 1234567890: mosquitto version X.X.X starting
mosquitto    | 1234567890: Config loaded from /mosquitto/config/mosquitto.conf
mosquitto    | 1234567890: Opening ipv4 listen socket on port 1883.
mosquitto    | 1234567890: Opening websockets listen socket on port 9001.
mosquitto    | 1234567890: mosquitto version X.X.X running

Expected Cloudflared Logs

Successful tunnel connection logs include:

cloudflared  | Registered tunnel connection
cloudflared  | Connection <UUID> registered connIndex=0
cloudflared  | Route propagating

Sources: docker-compose.yml:1-18


Verify Public Accessibility

After deployment, the MQTT broker is accessible at https://<subdomain>.<domain>:443, where the subdomain and domain are configured in the Cloudflare Tunnel public hostname settings (see Cloudflare Tunnel Setup).

Important: The broker is not directly accessible on ports 1883 or 9001 from the public internet. All traffic is routed through Cloudflare’s network on port 443 using HTTPS/WSS protocols. Internal container communication uses HTTP on port 9001.

Sources: README.md:82-84


Container Lifecycle Management

Container State Transitions

Sources: docker-compose.yml:9-15


Stopping the System

Stop all containers while preserving their state:

This sends a SIGTERM signal to each container, allowing graceful shutdown. Containers can be restarted with docker compose start.

Sources: docker-compose.yml:1-18


Removing the Deployment

Stop and remove all containers, networks, and anonymous volumes:

This completely tears down the deployment. The next docker compose up will create fresh containers.

To also remove named volumes (use with caution):

Sources: docker-compose.yml:1-18


Restarting Services

Restart all services:

Restart a specific service:

Sources: docker-compose.yml:4-17


Viewing Live Container Processes

Inspect running processes inside containers:

This displays process information for each running container.


Executing Commands in Containers

Execute a command in a running container:

This opens an interactive shell inside the specified container. Useful for debugging and inspecting the container’s filesystem.

Sources: docker-compose.yml:6-13


Deployment Verification Checklist

Use this checklist to confirm successful deployment:

  • .env file exists with valid CLOUDFLARE_TUNNEL_TOKEN
  • mosquitto.conf file exists in the project root
  • docker compose ps shows both containers with STATUS: Up
  • docker compose logs mosquitto shows listeners bound on ports 1883 and 9001
  • docker compose logs cloudflared shows tunnel registered and connection established
  • Public hostname resolves to Cloudflare’s network
  • MQTT client can connect to https://<subdomain>.<domain>:443

Sources: README.md:74-84 docker-compose.yml:1-18


Common Deployment Issues

This section provides brief guidance on common deployment failures. For comprehensive troubleshooting, see Troubleshooting.

IssuePossible CauseQuick Resolution
Container exits immediatelyMissing or invalid CLOUDFLARE_TUNNEL_TOKENVerify .env file and token validity
cloudflared fails to startToken expired or revokedRegenerate token in Cloudflare dashboard
mosquitto fails to startSyntax error in mosquitto.confCheck configuration file syntax
Cannot connect to public URLTunnel not registered or hostname misconfiguredVerify public hostname configuration in Cloudflare
Port binding errorsPort already in use on hostContainers do not expose ports to host by default; check for conflicting services

Sources: README.md84 docker-compose.yml:1-18


Restart Policy Behavior

Both containers are configured with restart: unless-stopped (docker-compose.yml:9-15), which provides automatic recovery:

  • Container Crash: Automatically restarts
  • Docker Daemon Restart: Automatically restarts (unless manually stopped)
  • Manual Stop: Does not automatically restart until explicitly started

This policy ensures high availability without manual intervention after transient failures or system reboots.

Sources: docker-compose.yml:9-15


Next Steps

After successful deployment:

  1. Test MQTT connectivity using an MQTT client (see Testing Connection)
  2. Review component documentation (see Components)
  3. Implement monitoring (see Monitoring and Health Checks)
  4. Consider production hardening (see Production Deployment Considerations)

Sources: README.md:82-84

Dismiss

Refresh this wiki

Enter email to refresh