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.

docker-compose.yml Reference

Relevant source files

Purpose and Scope

This document provides a complete technical reference for the docker-compose.yml file, which orchestrates both the mosquitto MQTT broker and cloudflared tunnel services. It covers all configuration properties, service definitions, volume mounts, environment variables, and restart policies used in the system.

For conceptual information about how Docker Compose orchestrates the services, see Docker Compose Orchestration. For deployment procedures, see Deployment. For environment variable setup, see Environment Variables Reference.

Sources: docker-compose.yml:1-18


File Location and Structure

The docker-compose.yml file is located in the repository root directory and uses Docker Compose file format version 3.8. The file defines a multi-container application with two services that work together to provide secure, externally-accessible MQTT brokering.

graph TB
    subgraph "docker-compose.yml Structure"
        Root["version: '3.8'"]
Services["services:]
        
        subgraph Service Definitions"
            Mosquitto["mosquitto:]
            Cloudflared[cloudflared:]
        end
        
        subgraph Mosquitto Properties"
            MQ_Image["image: eclipse-mosquitto:latest"]
MQ_Container["container_name: mosquitto"]
MQ_Volumes["volumes: [./mosquitto.conf mount]"]
MQ_Restart["restart: unless-stopped"]
end
        
        subgraph "Cloudflared Properties"
            CF_Image["image: cloudflare/cloudflared:latest"]
CF_Container["container_name: cloudflared"]
CF_Command["command: tunnel ... run --token"]
CF_Restart["restart: unless-stopped"]
CF_Env["environment: [CLOUDFLARE_TUNNEL_TOKEN]"]
end
    end
    
 
   Root --> Services
 
   Services --> Mosquitto
 
   Services --> Cloudflared
    
 
   Mosquitto --> MQ_Image
 
   Mosquitto --> MQ_Container
 
   Mosquitto --> MQ_Volumes
 
   Mosquitto --> MQ_Restart
    
 
   Cloudflared --> CF_Image
 
   Cloudflared --> CF_Container
 
   Cloudflared --> CF_Command
 
   Cloudflared --> CF_Restart
 
   Cloudflared --> CF_Env

High-Level Structure

Sources: docker-compose.yml:1-18


Version Specification

PropertyValueLine
version'3.8'docker-compose.yml1

The file uses Docker Compose file format version 3.8, which supports all features required by this system including service definitions, volume mounts, environment variables, and restart policies. Version 3.8 is compatible with Docker Engine 19.03.0+ and provides the necessary capabilities for container orchestration.

Sources: docker-compose.yml1


Services Overview

The services section defines two containerized services that comprise the complete system. Both services run continuously and restart automatically on failure.

graph LR
    subgraph "Docker Compose Services"
        subgraph "mosquitto Service"
            MQ_Runtime["Container: mosquitto"]
MQ_Base["Base Image: eclipse-mosquitto:latest"]
MQ_Config["Config Volume Mount"]
MQ_Policy["Restart: unless-stopped"]
end
        
        subgraph "cloudflared Service"
            CF_Runtime["Container: cloudflared"]
CF_Base["Base Image: cloudflare/cloudflared:latest"]
CF_Token["Environment: CLOUDFLARE_TUNNEL_TOKEN"]
CF_Cmd["Command: tunnel run"]
CF_Policy["Restart: unless-stopped"]
end
    end
    
    subgraph "External Resources"
        MosqConf["./mosquitto.conf"]
EnvFile[".env File"]
end
    
 
   MosqConf -.-> MQ_Config
 
   EnvFile -.-> CF_Token
    
 
   CF_Runtime -->|Proxies to| MQ_Runtime

Service Composition Diagram

Sources: docker-compose.yml:3-18


Mosquitto Service Configuration

The mosquitto service runs the Eclipse Mosquitto MQTT broker. It is defined starting at line 4 and includes image specification, container naming, volume configuration, and restart policy.

Service Properties

PropertyValueLineDescription
imageeclipse-mosquitto:latestdocker-compose.yml5Official Eclipse Mosquitto Docker image, latest version
container_namemosquittodocker-compose.yml6Fixed container name for internal DNS resolution
volumes./mosquitto.conf:/mosquitto/config/mosquitto.confdocker-compose.yml:7-8Mounts local config file into container
restartunless-stoppeddocker-compose.yml9Automatic restart policy

Image Specification

docker-compose.yml5 specifies eclipse-mosquitto:latest as the base image. This pulls the official Mosquitto image from Docker Hub. The latest tag ensures the most recent stable version is used, though this can be pinned to a specific version for production deployments.

Container Name

docker-compose.yml6 sets a fixed container name mosquitto. This serves two purposes:

  1. Provides predictable DNS resolution within Docker's internal network
  2. Enables the cloudflared service to reference the broker at mosquitto:9001

Volume Mount Configuration

docker-compose.yml:7-8 configures a bind mount that makes the broker configuration available to the container:

volumes:
  - ./mosquitto.conf:/mosquitto/config/mosquitto.conf
ComponentValueDescription
Host Path./mosquitto.confRelative path from docker-compose.yml location
Container Path/mosquitto/config/mosquitto.confStandard Mosquitto config location
Mount TypeBind mountDirect filesystem mapping
graph LR
    HostFS["Host Filesystem\n./mosquitto.conf"]
Mount["Volume Mount\nBind Type"]
ContainerFS["Container Filesystem\n/mosquitto/config/mosquitto.conf"]
Process["mosquitto Process\nReads Config"]
HostFS -->|Mounted by Docker| Mount
 
   Mount -->|Accessible at| ContainerFS
 
   ContainerFS -->|Read by| Process

This mount allows configuration changes without rebuilding the container image. The mosquitto process reads this configuration on startup.

Volume Mount Flow

Sources: docker-compose.yml:4-9


Cloudflared Service Configuration

The cloudflared service establishes a secure tunnel to Cloudflare's network. It is defined starting at line 11 and includes image specification, container naming, command configuration, environment variables, and restart policy.

Service Properties

PropertyValueLineDescription
imagecloudflare/cloudflared:latestdocker-compose.yml12Official Cloudflare Tunnel client image
container_namecloudflareddocker-compose.yml13Fixed container name
commandtunnel --no-autoupdate run --token ${CLOUDFLARE_TUNNEL_TOKEN}docker-compose.yml14Command with token interpolation
restartunless-stoppeddocker-compose.yml15Automatic restart policy
environmentCLOUDFLARE_TUNNEL_TOKENdocker-compose.yml:16-17Environment variable declaration

Image Specification

docker-compose.yml12 specifies cloudflare/cloudflared:latest as the base image. This is the official Cloudflare Tunnel client maintained by Cloudflare.

Command Override

docker-compose.yml14 overrides the default container command with:

tunnel --no-autoupdate run --token ${CLOUDFLARE_TUNNEL_TOKEN}
ArgumentPurpose
tunnelMain cloudflared subcommand for tunnel operations
--no-autoupdateDisables automatic updates within container (container restart handles updates)
runStarts the tunnel using token authentication
--tokenSpecifies authentication token (value from environment variable)
${CLOUDFLARE_TUNNEL_TOKEN}Environment variable interpolation by Docker Compose

Environment Variables

docker-compose.yml:16-17 declares the environment variable section:

graph TB
    EnvFile[".env File\nCLOUDFLARE_TUNNEL_TOKEN=xxx"]
Compose["docker-compose.yml\nEnvironment Declaration"]
Runtime["Container Runtime Environment\nCLOUDFLARE_TUNNEL_TOKEN=xxx"]
Command["Command Execution\ntunnel run --token xxx"]
EnvFile -->|Read by docker-compose| Compose
 
   Compose -->|Passes to container| Runtime
 
   Runtime -->|Interpolated in| Command
environment:
  - CLOUDFLARE_TUNNEL_TOKEN

This configuration tells Docker Compose to pass the CLOUDFLARE_TUNNEL_TOKEN environment variable from the host (typically loaded from .env file) into the container. The variable's value is then used in the command string via ${CLOUDFLARE_TUNNEL_TOKEN} interpolation.

Environment Variable Flow

Sources: docker-compose.yml:11-17


Restart Policy Configuration

Both services use restart: unless-stopped docker-compose.yml:9-15 This restart policy ensures containers automatically restart under most failure conditions but respect explicit stop commands.

Restart Policy Behavior

ScenarioBehavior
Container exits with errorAutomatically restarts
Container exits successfully (exit code 0)Automatically restarts
Docker daemon restartsContainer restarts
Manual docker stopContainer remains stopped
Manual docker-compose downContainer remains stopped
System rebootContainer does NOT restart (requires Docker to start stopped containers)

Alternative Restart Policies

While this system uses unless-stopped, Docker Compose supports other policies:

PolicyDescriptionUse Case
noNever restart (default)Development, debugging
alwaysAlways restart, even after manual stopMaximum availability
unless-stoppedRestart unless explicitly stoppedRecommended for most services
on-failure[:max-retries]Restart only on non-zero exitServices with proper shutdown

Sources: docker-compose.yml:9-15


graph TB
    subgraph "Docker Default Bridge Network"
        subgraph "cloudflared Container"
            CF_Process["cloudflared process"]
CF_DNS["DNS Resolution:\nmosquitto resolves to container IP"]
end
        
        subgraph "mosquitto Container"
            MQ_Process["mosquitto process"]
MQ_Listener["Listener: 0.0.0.0:9001"]
end
        
 
       CF_Process -->|HTTP Proxy to mosquitto:9001| CF_DNS
 
       CF_DNS -->|Resolves via Docker DNS| MQ_Listener
    end
    
    External["External Traffic\nfrom Cloudflare"]
External -.->|Via Tunnel| CF_Process

Service-to-Service Communication

Although not explicitly defined in the compose file, Docker Compose creates a default network for all services, enabling internal communication.

Internal Networking Model

The cloudflared service proxies traffic to mosquitto:9001, where mosquitto is resolved via Docker's internal DNS to the mosquitto container's IP address. This is made possible by the fixed container_name properties.

Sources: docker-compose.yml:6-13


Complete Property Reference

Top-Level Properties

PropertyTypeRequiredValue in File
versionstringNo (but recommended)'3.8'
servicesobjectYesContains mosquitto and cloudflared

Mosquitto Service Properties

Property PathTypeRequiredValueDefault if Omitted
services.mosquitto.imagestringYeseclipse-mosquitto:latestN/A
services.mosquitto.container_namestringNomosquittoAuto-generated
services.mosquitto.volumesarrayNo["./mosquitto.conf:/mosquitto/config/mosquitto.conf"]No volumes
services.mosquitto.restartstringNounless-stoppedno

Cloudflared Service Properties

Property PathTypeRequiredValueDefault if Omitted
services.cloudflared.imagestringYescloudflare/cloudflared:latestN/A
services.cloudflared.container_namestringNocloudflaredAuto-generated
services.cloudflared.commandstring/arrayNotunnel --no-autoupdate run --token ${CLOUDFLARE_TUNNEL_TOKEN}Image default
services.cloudflared.restartstringNounless-stoppedno
services.cloudflared.environmentarray/objectNo["CLOUDFLARE_TUNNEL_TOKEN"]No environment vars

Sources: docker-compose.yml:1-18


Deployment Commands

The following commands operate on this docker-compose.yml file:

CommandPurpose
docker-compose up -dStart all services in detached mode
docker-compose downStop and remove all containers
docker-compose psShow service status
docker-compose logsView combined logs
docker-compose logs mosquittoView mosquitto logs only
docker-compose logs cloudflaredView cloudflared logs only
docker-compose restartRestart all services
docker-compose pullPull latest images

Sources: docker-compose.yml:1-18


File Modification Considerations

When modifying docker-compose.yml, consider the following:

Image Version Pinning

The current configuration uses latest tags docker-compose.yml:5-12 For production environments, consider pinning specific versions:

Network Isolation

To add explicit network configuration:

Port Exposure

The current configuration does not expose ports to the host, which is intentional (all traffic goes through Cloudflare Tunnel). To expose ports for testing:

⚠️ Security Warning: Exposing ports bypasses the Cloudflare Tunnel security layer and should only be done in controlled environments.

Sources: docker-compose.yml:1-18


Configuration Validation

To validate the docker-compose.yml syntax:

This command parses the file, interpolates environment variables, and displays the resolved configuration. It will report syntax errors and missing environment variables.

Sources: docker-compose.yml:1-18