This documentation is part of the "Projects with Books" initiative at zenOSmosis.
The source code for this project is available on GitHub.
Production Considerations
Relevant source files
This document addresses critical considerations for deploying the Docker MQTT Mosquitto Cloudflare Tunnel system in production environments. It covers security hardening, authentication, data persistence, monitoring, resource management, and operational best practices.
The current implementation in the main branch prioritizes simplicity and ease of setup. For production deployments, additional configuration and hardening measures are required. For specific access control and encryption implementations, see the [protected-no-wildcard branch](https://github.com/jzombie/docker-mqtt-mosquitto-cloudflare-tunnel/blob/8a829fda/protected-no-wildcard branch) mentioned in Advanced Topics.
Security Hardening
Current Security Posture
The default configuration enables anonymous access to the MQTT broker without authentication:
This configuration allows any client reaching the broker through the Cloudflare Tunnel to publish and subscribe to any topic without credentials. While Cloudflare's network provides protection against network-level attacks (DDoS, direct IP exposure), the broker itself has no application-level access controls.
Production Security Diagram
graph TB
subgraph "External_Access"
Client["MQTT Client"]
end
subgraph "Cloudflare_Layer"
CFEdge["Cloudflare Edge\nDDoS Protection"]
CFTunnel["Cloudflare Tunnel\nEncrypted Transport"]
ZeroTrust["Zero Trust Access\nOptional Policy Enforcement"]
end
subgraph "Docker_Host"
subgraph "cloudflared_container"
CFDaemon["cloudflared service"]
TokenAuth["CLOUDFLARE_TUNNEL_TOKEN\nAuthentication"]
end
subgraph "mosquitto_container"
Broker["mosquitto broker"]
AnonymousAccess["allow_anonymous true\nLine 2"]
NoACL["No ACL configured"]
NoPassword["No password_file"]
end
end
Client --> CFEdge
CFEdge --> ZeroTrust
ZeroTrust --> CFTunnel
CFTunnel --> CFDaemon
TokenAuth -.->|Authenticates| CFDaemon
CFDaemon -->|Proxy to port 9001| Broker
AnonymousAccess -.->|Current Config| Broker
NoACL -.->|Production Risk| Broker
NoPassword -.->|Production Risk| Broker
Sources: mosquitto.conf:1-6 docker-compose.yml:11-17 README.md:1-73
Authentication Implementation
For production environments, disable anonymous access and implement authentication. Modify mosquitto.conf2 to include:
| Configuration Setting | Purpose | Implementation |
|---|---|---|
allow_anonymous false | Disable anonymous connections | Replace line 2 in mosquitto.conf |
password_file /mosquitto/config/passwordfile | Enable username/password authentication | Add volume mount in docker-compose.yml |
acl_file /mosquitto/config/aclfile | Implement topic-level access control | Mount ACL configuration file |
Password File Creation
The eclipse-mosquitto image includes the mosquitto_passwd utility for creating password files:
This file must be volume-mounted into the container at /mosquitto/config/passwordfile.
Sources: mosquitto.conf:1-6 docker-compose.yml:4-9
Topic Access Control (ACL)
The [protected-no-wildcard branch](https://github.com/jzombie/docker-mqtt-mosquitto-cloudflare-tunnel/blob/8a829fda/protected-no-wildcard branch) demonstrates ACL implementation. An ACL file defines per-user topic access permissions:
user alice
topic readwrite alice/#
user bob
topic read alice/public/#
topic readwrite bob/#
This restricts users to specific topic namespaces, preventing unauthorized access to other users' data.
Sources: README.md:5-11
Cloudflare Zero Trust Policies
Beyond broker-level authentication, Cloudflare Zero Trust Access can enforce additional policies before traffic reaches the tunnel:
- Email-based authentication
- IP address restrictions
- Geographic access controls
- Device posture requirements
These policies are configured in the Cloudflare Zero Trust dashboard and provide defense-in-depth.
Sources: README.md:27-29
Data Persistence and Backup
Current Persistence Configuration
The current docker-compose.yml:4-9 configuration has no explicit data volume mounts for persistence. The Mosquitto container stores retained messages and subscription data in ephemeral container storage, which is lost when the container is removed.
Data Persistence Architecture
graph TB
subgraph "Docker_Compose_Current"
MosqService["mosquitto service"]
ConfigVolume["./mosquitto.conf\nVolume Mount\nLine 8"]
NoDataVolume["No data volume\nProduction Risk"]
end
subgraph "Production_Persistence"
DataVolume["./data:/mosquitto/data\nRetained Messages"]
LogVolume["./log:/mosquitto/log\nBroker Logs"]
BackupProcess["Backup Strategy\nRequired"]
end
subgraph "Encrypted_Storage"
GoCryptFS["gocryptfs\nEncrypted Filesystem\nprotected-no-wildcard"]
end
ConfigVolume --> MosqService
NoDataVolume -.->|Should Add| DataVolume
NoDataVolume -.->|Should Add| LogVolume
DataVolume --> BackupProcess
LogVolume --> BackupProcess
GoCryptFS -.->|Optional Enhancement| DataVolume
Sources: docker-compose.yml:7-8 README.md:8-9
Implementing Persistent Storage
Add volume mounts to the mosquitto service definition in docker-compose.yml:4-9:
| Volume Mount | Purpose | Considerations |
|---|---|---|
./data:/mosquitto/data | Persist retained messages and subscriptions | Ensure host directory has appropriate permissions |
./log:/mosquitto/log | Persist broker logs | Configure log rotation to prevent disk exhaustion |
Update mosquitto.conf to enable persistence:
persistence true
persistence_location /mosquitto/data/
autosave_interval 300
The autosave_interval setting controls how frequently the broker writes in-memory state to disk (in seconds).
Sources: docker-compose.yml:4-9 mosquitto.conf:1-6
Encrypted Retained Messages
The [protected-no-wildcard branch](https://github.com/jzombie/docker-mqtt-mosquitto-cloudflare-tunnel/blob/8a829fda/protected-no-wildcard branch) implements encrypted storage for retained messages using gocryptfs. This provides at-rest encryption for sensitive MQTT data stored on disk.
Implementation requires:
- Installing gocryptfs on the Docker host
- Creating an encrypted filesystem mounted at the data directory
- Configuring automatic unlocking with secure key management
See Encrypted Retained Messages for detailed implementation guidance.
Sources: README.md:8-9
Backup Strategy
Production deployments require automated backup procedures:
| Backup Target | Frequency | Retention | Implementation |
|---|---|---|---|
| Mosquitto data directory | Daily | 30 days | Filesystem backup tools (rsync, restic, etc.) |
| mosquitto.conf | On change | Version control | Git commit and push |
| Password and ACL files | On change | Version control with encryption | git-crypt or external secrets management |
| Cloudflare tunnel configuration | N/A | Cloudflare dashboard maintains configuration | Document tunnel setup procedures |
Disaster Recovery Testing
Regularly test restoration procedures:
- Stop the
mosquittoservice - Restore backed-up data directory
- Verify container startup with
docker compose logs mosquitto - Validate client connectivity
Sources: docker-compose.yml:4-9
Monitoring and Logging
Current Logging Configuration
The default configuration provides minimal logging visibility. Container logs are available via docker compose logs but are not persisted or aggregated.
Production Monitoring Architecture
graph TB
subgraph "Container_Logs"
MosqLogs["mosquitto container\nstdout/stderr"]
CFLogs["cloudflared container\nstdout/stderr"]
end
subgraph "Docker_Logging_Driver"
DefaultDriver["json-file driver\nNo configuration"]
ProductionDriver["json-file with rotation\nor external driver"]
end
subgraph "Log_Aggregation"
Syslog["Syslog\nCentralized Logging"]
Fluentd["Fluentd\nLog Forwarding"]
CloudWatch["CloudWatch\nAWS Integration"]
end
subgraph "Metrics_Collection"
MosqMetrics["Mosquitto $SYS Topics\nBroker Statistics"]
PrometheusExporter["mosquitto-exporter\nPrometheus Metrics"]
AlertManager["Alert Manager\nThreshold Alerts"]
end
MosqLogs --> DefaultDriver
CFLogs --> DefaultDriver
DefaultDriver -.->|Should Configure| ProductionDriver
ProductionDriver --> Syslog
ProductionDriver --> Fluentd
ProductionDriver --> CloudWatch
MosqMetrics --> PrometheusExporter
PrometheusExporter --> AlertManager
Sources: docker-compose.yml:1-18
Docker Logging Configuration
Configure log rotation in docker-compose.yml:4-9 to prevent disk exhaustion:
This limits each container to 30MB of log storage (3 files × 10MB).
Alternative Logging Drivers:
| Driver | Use Case | Configuration |
|---|---|---|
syslog | Central syslog server | Requires syslog-address option |
fluentd | Log aggregation pipeline | Requires Fluentd server |
awslogs | AWS CloudWatch integration | Requires AWS credentials |
Sources: docker-compose.yml:4-9
Mosquitto Logging Configuration
Add logging directives to mosquitto.conf:1-6:
log_dest file /mosquitto/log/mosquitto.log
log_type all
log_timestamp true
log_timestamp_format %Y-%m-%d %H:%M:%S
This requires a volume mount for /mosquitto/log as described in [Data Persistence](https://github.com/jzombie/docker-mqtt-mosquitto-cloudflare-tunnel/blob/8a829fda/Data Persistence)
Sources: mosquitto.conf:1-6
Monitoring Mosquitto Broker Statistics
Mosquitto publishes internal statistics to $SYS topics. Monitor these for operational insights:
| Topic | Metric | Threshold Alert |
|---|---|---|
$SYS/broker/clients/connected | Active client count | Alert if exceeds capacity planning |
$SYS/broker/load/messages/sent/1min | Message throughput | Alert on sudden drops (potential issue) |
$SYS/broker/uptime | Broker uptime | Alert on unexpected restarts |
$SYS/broker/heap/current | Memory usage | Alert if approaching limits |
Subscribe to these topics using an MQTT client or integrate with monitoring systems using mosquitto-exporter for Prometheus integration.
Sources: mosquitto.conf:1-6
Resource Management and Performance
Current Resource Configuration
The docker-compose.yml:4-9 configuration has no resource limits defined. Containers can consume unlimited CPU and memory, potentially impacting host system stability.
Resource Constraint Architecture
graph TB
subgraph "Docker_Compose_Services"
MosqService["mosquitto service\nNo limits defined"]
CFService["cloudflared service\nNo limits defined"]
end
subgraph "Host_Resources"
HostCPU["Host CPU\nShared Resource"]
HostMem["Host Memory\nShared Resource"]
HostDisk["Host Disk I/O\nShared Resource"]
end
subgraph "Production_Limits"
CPULimit["cpus: 2.0\ncpu_shares: 1024"]
MemLimit["mem_limit: 2g\nmem_reservation: 1g"]
IOLimit["blkio_config\nI/O Throttling"]
end
MosqService -.->|Unrestricted Access| HostCPU
MosqService -.->|Unrestricted Access| HostMem
CFService -.->|Unrestricted Access| HostCPU
CFService -.->|Unrestricted Access| HostMem
CPULimit -.->|Should Apply| MosqService
MemLimit -.->|Should Apply| MosqService
IOLimit -.->|Should Apply| MosqService
Sources: docker-compose.yml:4-9
Implementing Resource Limits
Add resource constraints to both services in docker-compose.yml:4-9:
Resource Sizing Guidelines:
| Service | CPU Limit | Memory Limit | Rationale |
|---|---|---|---|
mosquitto | 2.0 CPUs | 2GB | Message processing and retained message storage |
cloudflared | 1.0 CPU | 512MB | Lightweight proxy with minimal processing overhead |
Adjust based on observed load. Monitor with docker stats.
Sources: docker-compose.yml:4-9
Performance Tuning
For high-throughput scenarios, tune Mosquitto configuration in mosquitto.conf:1-6:
| Parameter | Default | Production Recommendation | Purpose |
|---|---|---|---|
max_connections | -1 (unlimited) | Set based on capacity | Prevent resource exhaustion |
max_inflight_messages | 20 | 100-1000 for QoS > 0 | Increase throughput for reliable messaging |
max_queued_messages | 1000 | 10000-100000 | Buffer for slow consumers |
max_packet_size | 0 (unlimited) | 10485760 (10MB) | Prevent oversized packets |
Sources: mosquitto.conf:1-6
Connection Limit Configuration
To prevent resource exhaustion attacks, configure connection limits:
max_connections 1000
Set based on expected client count with 20-30% headroom. Monitor $SYS/broker/clients/maximum to track peak usage.
Sources: mosquitto.conf:1-6
High Availability and Scaling
Current Single-Instance Architecture
The current deployment runs single instances of both the mosquitto and cloudflared services as defined in docker-compose.yml:4-17 This creates single points of failure.
High Availability Architecture Options
graph TB
subgraph "Current_Architecture"
SingleMosq["mosquitto container\nSingle Instance"]
SingleCF["cloudflared container\nSingle Instance"]
end
subgraph "HA_Option_1_Multiple_Tunnels"
MosqPrimary["mosquitto primary\nActive Broker"]
CF1["cloudflared tunnel 1"]
CF2["cloudflared tunnel 2"]
CFN["cloudflared tunnel N"]
CF1 --> MosqPrimary
CF2 --> MosqPrimary
CFN --> MosqPrimary
end
subgraph "HA_Option_2_Clustering"
MosqBroker1["mosquitto broker 1\nwith Bridge"]
MosqBroker2["mosquitto broker 2\nwith Bridge"]
MosqBroker1 <-->|Bridge Connection| MosqBroker2
end
subgraph "HA_Option_3_Load_Balancer"
CFTunnelHA["cloudflared\nMultiple Replicas"]
LoadBalancer["Cloudflare LB\nHealth Checks"]
MosqCluster["mosquitto instances\nShared Storage"]
LoadBalancer --> CFTunnelHA
CFTunnelHA --> MosqCluster
end
Sources: docker-compose.yml:4-17
Multiple Cloudflare Tunnels
Deploy multiple cloudflared replicas for tunnel redundancy:
Cloudflare automatically load-balances across active tunnel connections. This provides tunnel-level redundancy but not broker-level redundancy.
Sources: docker-compose.yml:11-17
Mosquitto Bridge Configuration
For multi-broker redundancy, configure Mosquitto bridges. Each broker can bridge topics to a central broker or peer-to-peer:
connection bridge-to-primary
address primary-broker.example.com:1883
topic # both 0
This configuration bridges all topics bidirectionally. Bridge connections require network connectivity between brokers, which may require additional Cloudflare Tunnel configuration.
Sources: mosquitto.conf:1-6
Scaling Considerations
| Scaling Dimension | Approach | Considerations |
|---|---|---|
| Vertical | Increase resource limits in docker-compose.yml | Limited by host capacity; simplest approach |
| Horizontal (Clients) | Deploy multiple cloudflared replicas | Cloudflare handles load distribution |
| Horizontal (Brokers) | Bridge multiple Mosquitto instances | Requires shared storage or message replication |
| Geographic | Deploy instances in multiple regions with bridges | Reduces latency for global clients |
Sources: docker-compose.yml:4-17
Network Security
Cloudflare Tunnel Security Model
The Cloudflare Tunnel architecture eliminates inbound firewall rules. All traffic flows through the tunnel established by the cloudflared container as configured in docker-compose.yml:11-17
Network Isolation Architecture
Sources: docker-compose.yml:11-17 README.md:15-73
Docker Network Isolation
The current configuration uses Docker's default bridge network. For production, create an isolated network:
The internal: false setting allows the cloudflared service to establish outbound connections to Cloudflare while preventing direct external access to the mosquitto service.
Sources: docker-compose.yml:1-18
Port Exposure
The current docker-compose.yml:4-9 configuration does not expose ports on the host. This is intentional and should be maintained. All MQTT traffic flows through the Cloudflare Tunnel.
Do not add port mappings like:
Direct port exposure bypasses Cloudflare's protection layer.
Sources: docker-compose.yml:4-9
Rate Limiting
Implement application-level rate limiting in mosquitto.conf:1-6 to prevent abuse:
max_publish_rate 100
max_subscribe_rate 100
These settings limit each client to 100 publishes and 100 subscriptions per second. Adjust based on legitimate client behavior.
Sources: mosquitto.conf:1-6
Maintenance and Updates
Current Update Strategy
Both services use the latest tag as specified in docker-compose.yml:5-12:
eclipse-mosquitto:latestcloudflare/cloudflared:latest
graph TB
subgraph "Current_Configuration"
MosqLatest["mosquitto\neclipse-mosquitto:latest\nLine 5"]
CFLatest["cloudflared\ncloudflare/cloudflared:latest\nLine 12"]
end
subgraph "Production_Versioning"
MosqPinned["mosquitto\neclipse-mosquitto:2.0.18"]
CFPinned["cloudflared\ncloudflare/cloudflared:2024.1.5"]
end
subgraph "Update_Process"
TestEnv["Test Environment\nValidate New Version"]
Rollback["Rollback Plan\nPrevious Version Tag"]
UpdateSchedule["Maintenance Window\nScheduled Updates"]
end
MosqLatest -.->|Production Risk| MosqPinned
CFLatest -.->|Production Risk| CFPinned
MosqPinned --> TestEnv
CFPinned --> TestEnv
TestEnv --> UpdateSchedule
UpdateSchedule --> Rollback
This approach automatically pulls the newest versions but provides no version control or rollback capability.
Update Management Architecture
Sources: docker-compose.yml:5-12
Pinning Image Versions
Update docker-compose.yml:5-12 to use specific version tags:
Version Selection Strategy:
| Image | Version Selection | Rationale |
|---|---|---|
eclipse-mosquitto | Use specific minor version (e.g., 2.0.18) | Ensures stable MQTT protocol implementation |
cloudflare/cloudflared | Use dated release (e.g., 2024.1.5) | Cloudflare releases are date-tagged and stable |
Sources: docker-compose.yml:5-12
Update Procedure
Follow this procedure for production updates:
- Check Release Notes : Review changelogs for both Mosquitto and cloudflared
- Test in Non-Production : Deploy new versions in a test environment
- Backup Current State : Backup data directory and configuration files
- Schedule Maintenance Window : Notify users of planned downtime
- Update docker-compose.yml : Change image tags to new versions
- Pull New Images :
docker compose pull - Restart Services :
docker compose down && docker compose up -d - Verify Operation : Check logs with
docker compose logs -f - Monitor Metrics : Watch
$SYStopics for anomalies
Rollback Procedure:
If issues arise after update:
- Stop services:
docker compose down - Revert image tags in docker-compose.yml:5-12 to previous versions
- Restore data directory from backup if necessary
- Start services:
docker compose up -d
Sources: docker-compose.yml:5-12
Automated Update Monitoring
Monitor for new releases using:
- GitHub watch notifications for mosquitto and cloudflared
- Docker Hub webhooks for image updates
- Automated security scanning tools (e.g., Trivy)
Sources: docker-compose.yml:5-12
Cloudflared Auto-Update Disabled
The --no-autoupdate flag in docker-compose.yml13 disables automatic updates for cloudflared:
This ensures version control and prevents unexpected behavior from automatic updates. Maintain this flag in production deployments.
Sources: docker-compose.yml13
graph TB
subgraph "Test_Environment"
TestCompose["docker-compose.yml\nTest Configuration"]
TestMosq["mosquitto container\nTest Instance"]
TestCF["cloudflared container\nSeparate Tunnel"]
end
subgraph "Test_Procedures"
ConnTest["Connection Test\nMQTT Client Connect"]
PubSubTest["Pub/Sub Test\nMessage Exchange"]
LoadTest["Load Test\nMultiple Clients"]
FailoverTest["Failover Test\nContainer Restart"]
end
subgraph "Production_Environment"
ProdCompose["docker-compose.yml\nProduction Config"]
ProdMosq["mosquitto container\nProduction Instance"]
ProdCF["cloudflared container\nProduction Tunnel"]
end
TestCompose --> TestMosq
TestCompose --> TestCF
TestMosq --> ConnTest
ConnTest --> PubSubTest
PubSubTest --> LoadTest
LoadTest --> FailoverTest
FailoverTest -.->|Validation Pass| ProdCompose
ProdCompose --> ProdMosq
ProdCompose --> ProdCF
Testing and Validation
Pre-Production Testing
Before deploying to production, validate the complete system:
Test Environment Setup Diagram
Sources: docker-compose.yml:1-18
Connection Testing
Test MQTT connectivity using command-line clients:
WebSocket Connection (Port 9001):
Test Scenarios:
| Test Case | Command | Expected Result |
|---|---|---|
| Subscribe to topic | mosquitto_sub -h hostname -t test/# | Connection established |
| Publish message | mosquitto_pub -h hostname -t test/msg -m "test" | Message received by subscribers |
| Retained message | mosquitto_pub -h hostname -t test/retained -m "data" -r | Message persisted and delivered to new subscribers |
| QoS 1 delivery | mosquitto_pub -h hostname -t test/qos1 -m "data" -q 1 | PUBACK received |
| QoS 2 delivery | mosquitto_pub -h hostname -t test/qos2 -m "data" -q 2 | PUBREC/PUBREL/PUBCOMP exchange |
Sources: mosquitto.conf:4-5 README.md:59-64
Load Testing
Use tools like mqtt-stresser or [JMeter MQTT Plugin](https://github.com/jzombie/docker-mqtt-mosquitto-cloudflare-tunnel/blob/8a829fda/JMeter MQTT Plugin) to validate performance under load:
Monitor broker metrics during load tests:
- CPU and memory usage:
docker stats mosquitto - Connection count: Subscribe to
$SYS/broker/clients/connected - Message rate: Subscribe to
$SYS/broker/load/messages/sent/1min
Sources: docker-compose.yml:4-9
Container Health Checks
Add health checks to docker-compose.yml:4-9 for automated failure detection:
This health check subscribes to a $SYS topic to verify the broker is responding. The start_period allows time for container initialization.
Sources: docker-compose.yml:4-9
Automated Testing with CI
The existing CI workflow in .github/workflows/ci.yml tests Mosquitto startup. Enhance this for production validation:
- Test anonymous access is disabled (if authentication is configured)
- Test ACL enforcement (if ACL is configured)
- Test persistence by publishing retained messages and restarting the container
- Test WebSocket connectivity on port 9001
Sources: README.md1
Configuration Management
graph TB
subgraph "Development"
EnvSample[".env.sample\nTemplate Only"]
LocalEnv[".env\nActual Secrets"]
GitIgnore[".gitignore\nExcludes .env"]
end
subgraph "Version_Control"
GitRepo["Git Repository\nNo Secrets"]
end
subgraph "Production_Options"
DockerSecrets["Docker Secrets\nSwarm Mode"]
VaultIntegration["HashiCorp Vault\nExternal Secrets"]
EnvEncryption["git-crypt\nEncrypted .env"]
CloudProvider["AWS Secrets Manager\nCloud Integration"]
end
subgraph "Runtime"
ComposeService["docker-compose.yml\nReferences ${VAR}"]
CFContainer["cloudflared container\nReceives Token"]
end
EnvSample -.->|Developer Copies| LocalEnv
GitIgnore -.->|Prevents Commit| LocalEnv
LocalEnv -->|Source for compose| ComposeService
GitIgnore --> GitRepo
DockerSecrets -.->|Alternative| ComposeService
VaultIntegration -.->|Alternative| ComposeService
EnvEncryption -.->|Alternative| GitRepo
CloudProvider -.->|Alternative| ComposeService
ComposeService --> CFContainer
Environment Variable Security
The CLOUDFLARE_TUNNEL_TOKEN in docker-compose.yml17 contains sensitive authentication credentials. Current security measures:
Secret Management Architecture
Sources: .env.sample docker-compose.yml:16-17
Docker Secrets (Swarm Mode)
For Docker Swarm deployments, use Docker secrets instead of environment variables:
Create the secret: echo "your-token" | docker secret create cloudflare_tunnel_token -
Sources: docker-compose.yml:13-17
External Secrets Management
For enterprise deployments, integrate with external secrets management:
| Solution | Integration Approach | Use Case |
|---|---|---|
| HashiCorp Vault | Vault agent sidecar or init container | Multi-service deployments |
| AWS Secrets Manager | ECS task execution role | AWS-hosted deployments |
| Azure Key Vault | Managed identity | Azure-hosted deployments |
| Google Secret Manager | Workload identity | GCP-hosted deployments |
Sources: docker-compose.yml:16-17
Configuration Validation
Before deployment, validate configuration files:
Mosquitto Configuration Test:
The -t flag tests the configuration without starting the broker.
Docker Compose Validation:
This validates docker-compose.yml syntax and interpolates environment variables.
Sources: mosquitto.conf:1-6 docker-compose.yml:1-18
graph TB
subgraph "Stateful_Components"
MosqData["mosquitto data\nRetained Messages"]
MosqConf["mosquitto.conf\nBroker Config"]
PasswordFile["passwordfile\nUser Credentials"]
ACLFile["aclfile\nAccess Control"]
EnvFile[".env\nTunnel Token"]
end
subgraph "Backup_Targets"
LocalBackup["Local Filesystem\nDaily Snapshots"]
RemoteBackup["Remote Storage\nEncrypted Copy"]
GitBackup["Git Repository\nConfig Files Only"]
end
subgraph "Recovery_Testing"
RestoreTest["Quarterly Recovery Test"]
DocumentRecovery["Recovery Runbook"]
RTO["Recovery Time Objective"]
RPO["Recovery Point Objective"]
end
MosqData --> LocalBackup
MosqConf --> GitBackup
PasswordFile --> RemoteBackup
ACLFile --> GitBackup
EnvFile --> RemoteBackup
LocalBackup --> RemoteBackup
LocalBackup --> RestoreTest
RemoteBackup --> RestoreTest
RestoreTest --> DocumentRecovery
DocumentRecovery --> RTO
DocumentRecovery --> RPO
Disaster Recovery
Backup Requirements
Production deployments require comprehensive backup procedures covering all stateful components.
Backup Architecture
Sources: docker-compose.yml:7-8 mosquitto.conf:1-6
Recovery Time Objective (RTO)
Define acceptable downtime for service restoration:
| Severity Level | RTO Target | Required Preparations |
|---|---|---|
| Critical (Data Loss) | 1 hour | Automated backup restoration scripts |
| Major (Service Down) | 4 hours | Documented recovery procedures |
| Minor (Degraded) | 24 hours | Manual recovery acceptable |
Sources: docker-compose.yml:1-18
Recovery Point Objective (RPO)
Define acceptable data loss:
| Data Type | RPO Target | Backup Frequency |
|---|---|---|
| Retained messages | 5 minutes | Continuous with autosave_interval 300 |
| Configuration files | On change | Git commit |
| User credentials | On change | Backup before modification |
Sources: mosquitto.conf:1-6
Recovery Procedures
Complete System Recovery:
- Provision new Docker host
- Install Docker Engine and docker-compose
- Clone repository:
git clone https://github.com/jzombie/docker-mqtt-mosquitto-cloudflare-tunnel - Restore
.envfile from secure backup - Restore
mosquitto.conf, password file, and ACL file from backup - Restore data directory from most recent backup
- Execute
docker compose pullto download images - Execute
docker compose up -dto start services - Verify operation with connection tests
Data-Only Recovery:
- Stop services:
docker compose down - Restore data directory from backup
- Start services:
docker compose up -d - Verify retained messages are accessible
Sources: docker-compose.yml:1-18
Testing Recovery Procedures
Quarterly disaster recovery tests validate recovery procedures:
- Document current system state
- Destroy test environment
- Execute recovery procedures
- Validate data integrity
- Measure actual RTO and RPO
- Update recovery documentation with lessons learned
Sources: docker-compose.yml:1-18
Cost Optimization
Cloudflare Tunnel Costs
Cloudflare Tunnel is available on the Free plan with limitations and paid plans for higher requirements:
| Plan | Cost | Tunnel Limit | Use Case |
|---|---|---|---|
| Free | $0/month | 1 user | Development, small deployments |
| Zero Trust Standard | $7/user/month | Up to 50 seats | Small teams |
| Zero Trust Enterprise | Custom | Unlimited | Large organizations |
For production MQTT deployments with minimal user access requirements, the Free plan may be sufficient if only the tunnel itself needs to be maintained (clients connect to MQTT, not individual users logging in).
Sources: README.md:19-20
Docker Resource Optimization
Right-size resource limits in docker-compose.yml:4-17 based on actual usage:
- Deploy with conservative limits
- Monitor actual resource consumption with
docker stats - Adjust limits to provide 20-30% headroom above peak usage
- Iterate monthly as load characteristics change
Resource Monitoring:
Sources: docker-compose.yml:4-17
Data Storage Optimization
Minimize storage costs for retained messages:
max_queued_bytes 10485760
This limits queued message storage to 10MB per client. Adjust based on message patterns.
For long-term message retention, consider:
- Implementing message TTL policies
- Archiving old retained messages to cheaper storage tiers
- Using compression for archived data
Sources: mosquitto.conf:1-6
Compliance and Auditing
Audit Logging
For compliance requirements, enable comprehensive audit logging in mosquitto.conf:1-6:
log_type error
log_type warning
log_type notice
log_type information
log_type subscribe
log_type unsubscribe
This logs all client subscriptions and unsubscriptions for audit trails.
Sources: mosquitto.conf:1-6
Data Retention Policies
Document data retention requirements:
| Data Type | Retention Period | Deletion Method |
|---|---|---|
| MQTT broker logs | 90 days | Automated log rotation |
| Retained messages | Based on business requirements | Manual or automated cleanup |
| Audit logs | 7 years (for some regulations) | Archive to cold storage |
Sources: mosquitto.conf:1-6
Privacy Considerations
For GDPR or similar privacy regulations:
- Implement user data isolation using ACLs (see Topic Access Control))
- Document message content and retention in privacy policy
- Implement data deletion procedures for retained messages
- Encrypt messages at rest (see Encrypted Retained Messages)
- Log data access for audit trails
Sources: README.md:5-11
Summary
Production deployment of the Docker MQTT Mosquitto Cloudflare Tunnel system requires significant hardening beyond the simple configuration in the main branch. Key production requirements:
- Security: Disable anonymous access (mosquitto.conf2), implement authentication and ACLs
- Persistence: Add data volume mounts to docker-compose.yml:4-9 for retained messages
- Monitoring: Configure logging, metrics collection, and alerting
- Resource Management: Define resource limits in docker-compose.yml:4-9
- High Availability: Deploy multiple tunnel replicas or broker instances with bridging
- Maintenance: Pin image versions in docker-compose.yml:5-12 and establish update procedures
- Testing: Implement health checks and load testing
- Disaster Recovery: Automate backups and document recovery procedures
The [protected-no-wildcard branch](https://github.com/jzombie/docker-mqtt-mosquitto-cloudflare-tunnel/blob/8a829fda/protected-no-wildcard branch) provides reference implementations for ACL-based access control and encrypted storage.
Sources: README.md:1-73 docker-compose.yml:1-18 mosquitto.conf:1-6
Dismiss
Refresh this wiki
This wiki was recently refreshed. Please wait 1 day to refresh again.
On this page
- Production Considerations
- Security Hardening
- Current Security Posture
- Authentication Implementation
- Topic Access Control (ACL)
- Cloudflare Zero Trust Policies
- Data Persistence and Backup
- Current Persistence Configuration
- Implementing Persistent Storage
- Encrypted Retained Messages
- Backup Strategy
- Monitoring and Logging
- Current Logging Configuration
- Docker Logging Configuration
- Mosquitto Logging Configuration
- Monitoring Mosquitto Broker Statistics
- Resource Management and Performance
- Current Resource Configuration
- Implementing Resource Limits
- Performance Tuning
- Connection Limit Configuration
- High Availability and Scaling
- Current Single-Instance Architecture
- Multiple Cloudflare Tunnels
- Mosquitto Bridge Configuration
- Scaling Considerations
- Network Security
- Cloudflare Tunnel Security Model
- Docker Network Isolation
- Port Exposure
- Rate Limiting
- Maintenance and Updates
- Current Update Strategy
- Pinning Image Versions
- Update Procedure
- Automated Update Monitoring
- Cloudflared Auto-Update Disabled
- Testing and Validation
- Pre-Production Testing
- Connection Testing
- Load Testing
- Container Health Checks
- Automated Testing with CI
- Configuration Management
- Environment Variable Security
- Docker Secrets (Swarm Mode)
- External Secrets Management
- Configuration Validation
- Disaster Recovery
- Backup Requirements
- Recovery Time Objective (RTO)
- Recovery Point Objective (RPO)
- Recovery Procedures
- Testing Recovery Procedures
- Cost Optimization
- Cloudflare Tunnel Costs
- Docker Resource Optimization
- Data Storage Optimization
- Compliance and Auditing
- Audit Logging
- Data Retention Policies
- Privacy Considerations
- Summary