Add comprehensive caddy-docker-proxy integration with auto-labeling
- Reference caddy-docker-proxy GitHub project for automatic HTTPS - Provide complete production-ready docker-compose.yml with Cloudflare DNS - Add environment configuration (.env) and deployment instructions - Document --transport http-streamable auto-labeling feature - Show how auto-labeling eliminates manual caddy configuration - Include simplified deployment with environment-based detection - Add benefits of streaming mode: SSE, real-time monitoring, zero config - Provide step-by-step production deployment example
This commit is contained in:
parent
b4d39cfdc9
commit
1ca195607e
261
README.md
261
README.md
@ -1153,71 +1153,248 @@ mqtt-{subdomain}.yourdomain.com {
|
|||||||
# Devices get automatic HTTPS, load balancing, DDoS protection
|
# Devices get automatic HTTPS, load balancing, DDoS protection
|
||||||
```
|
```
|
||||||
|
|
||||||
### 🔧 Docker Compose Integration
|
### 🔧 Docker Compose Integration with caddy-docker-proxy
|
||||||
|
|
||||||
**Complete Stack with caddy-docker-proxy:**
|
**Using [caddy-docker-proxy](https://github.com/lucaslorentz/caddy-docker-proxy)** for automatic HTTPS and container discovery.
|
||||||
|
|
||||||
|
> **caddy-docker-proxy** automatically generates Caddyfile configurations from Docker container labels, eliminating manual reverse proxy setup. Perfect for dynamic broker spawning!
|
||||||
|
|
||||||
|
**Complete Production Stack:**
|
||||||
```yaml
|
```yaml
|
||||||
# docker-compose.yml
|
# docker-compose.yml
|
||||||
|
version: "3.8"
|
||||||
|
|
||||||
services:
|
services:
|
||||||
mcmqtt:
|
caddy:
|
||||||
image: python:3.11-slim
|
image: lucaslorentz/caddy-docker-proxy:ci-alpine
|
||||||
command: uvx mcmqtt --transport http --port 3000
|
ports:
|
||||||
|
- "80:80"
|
||||||
|
- "443:443"
|
||||||
|
environment:
|
||||||
|
# Enable Docker provider for automatic container discovery
|
||||||
|
CADDY_INGRESS_NETWORKS: caddy
|
||||||
|
# Cloudflare API token for DNS challenge (wildcard certificates)
|
||||||
|
CLOUDFLARE_API_TOKEN: ${CLOUDFLARE_API_TOKEN}
|
||||||
|
networks:
|
||||||
|
- caddy
|
||||||
volumes:
|
volumes:
|
||||||
- /var/run/docker.sock:/var/run/docker.sock
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
networks:
|
- caddy_data:/data
|
||||||
- caddy
|
- caddy_config:/config
|
||||||
|
restart: unless-stopped
|
||||||
labels:
|
labels:
|
||||||
# caddy-docker-proxy automatically adds to Caddyfile
|
# Global TLS configuration for wildcard certificates
|
||||||
caddy: mqtt-control.yourdomain.com
|
caddy.tls.dns: cloudflare
|
||||||
caddy.reverse_proxy: "{{upstreams 3000}}"
|
|
||||||
caddy.tls: internal # or use DNS challenge for public
|
mcmqtt:
|
||||||
|
image: python:3.11-slim
|
||||||
# Example spawned broker container (created by mcmqtt)
|
# http-streamable automatically configures caddy labels
|
||||||
mqtt-broker-customer-123:
|
command: uvx mcmqtt --transport http-streamable --port 3000 --hostname mqtt-control.${DOMAIN}
|
||||||
image: python:3.11-slim
|
volumes:
|
||||||
command: uvx amqtt --config /broker.yaml
|
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||||
networks:
|
networks:
|
||||||
- caddy
|
- caddy
|
||||||
labels:
|
restart: unless-stopped
|
||||||
# Automatic HTTPS routing via caddy-docker-proxy
|
environment:
|
||||||
caddy: customer-123.mqtt.yourdomain.com
|
- DOMAIN=${DOMAIN}
|
||||||
caddy.reverse_proxy: "{{upstreams 1883}}"
|
- CADDY_NETWORK=caddy
|
||||||
|
# Labels automatically added by --transport http-streamable
|
||||||
|
# No manual caddy labels needed!
|
||||||
|
depends_on:
|
||||||
|
- caddy
|
||||||
|
|
||||||
|
# Optional: Web dashboard for broker management
|
||||||
|
mqtt-dashboard:
|
||||||
|
image: nginx:alpine
|
||||||
|
volumes:
|
||||||
|
- ./dashboard:/usr/share/nginx/html:ro
|
||||||
|
networks:
|
||||||
|
- caddy
|
||||||
|
labels:
|
||||||
|
caddy: mqtt-dashboard.yourdomain.com
|
||||||
|
caddy.reverse_proxy: "{{upstreams 80}}"
|
||||||
caddy.tls.dns: cloudflare
|
caddy.tls.dns: cloudflare
|
||||||
# WebSocket support
|
|
||||||
caddy.handle_path: "/ws"
|
|
||||||
caddy.handle_path.reverse_proxy: "{{upstreams 9001}}"
|
|
||||||
caddy.@websocket.header: "Connection *Upgrade*"
|
|
||||||
caddy.@websocket.header_2: "Upgrade websocket"
|
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
caddy:
|
caddy:
|
||||||
external: true # Managed by load-balancers/caddy
|
external: false
|
||||||
|
name: caddy
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
caddy_data:
|
||||||
|
external: true
|
||||||
|
caddy_config:
|
||||||
|
external: true
|
||||||
```
|
```
|
||||||
|
|
||||||
**The Magic: Just Labels = Instant HTTPS Routing!**
|
**Environment Configuration (.env):**
|
||||||
```bash
|
```bash
|
||||||
# When mcmqtt spawns a broker, it adds these labels:
|
# .env file
|
||||||
|
COMPOSE_PROJECT_NAME=mcmqtt-production
|
||||||
|
|
||||||
|
# Cloudflare DNS challenge for wildcard certificates
|
||||||
|
CLOUDFLARE_API_TOKEN=your_cloudflare_global_api_key_here
|
||||||
|
|
||||||
|
# Domain configuration
|
||||||
|
DOMAIN=yourdomain.com
|
||||||
|
MQTT_SUBDOMAIN=mqtt
|
||||||
|
|
||||||
|
# Optional: Basic auth for admin interfaces
|
||||||
|
ADMIN_USER=admin
|
||||||
|
ADMIN_PASSWORD_HASH=$2a$14$hash_your_password_here
|
||||||
|
```
|
||||||
|
|
||||||
|
**Setup Instructions:**
|
||||||
|
```bash
|
||||||
|
# 1. Create external volumes for Caddy data persistence
|
||||||
|
docker volume create caddy_data
|
||||||
|
docker volume create caddy_config
|
||||||
|
|
||||||
|
# 2. Configure environment variables
|
||||||
|
cp .env.example .env
|
||||||
|
# Edit .env with your domain and Cloudflare token
|
||||||
|
|
||||||
|
# 3. Deploy the stack
|
||||||
|
docker compose up -d
|
||||||
|
|
||||||
|
# 4. Verify Caddy is running
|
||||||
|
docker compose logs caddy
|
||||||
|
|
||||||
|
# 5. Test mcmqtt control interface
|
||||||
|
curl https://mqtt-control.yourdomain.com/health
|
||||||
|
```
|
||||||
|
|
||||||
|
**How Dynamic Broker Spawning Works:**
|
||||||
|
```bash
|
||||||
|
# 1. User calls mqtt_spawn_broker tool
|
||||||
{
|
{
|
||||||
"tool": "mqtt_spawn_broker",
|
"tool": "mqtt_spawn_broker",
|
||||||
"arguments": {
|
"arguments": {
|
||||||
"name": "api-coordination",
|
"name": "customer-acme-prod",
|
||||||
"websocket_port": 9001,
|
"websocket_port": 9001,
|
||||||
"caddy_labels": {
|
"public_hostname": "acme.mqtt.yourdomain.com",
|
||||||
"caddy": "api-coord.mqtt.yourdomain.com",
|
"auth_required": true,
|
||||||
"caddy.reverse_proxy": "{{upstreams 1883}}",
|
"max_connections": 1000
|
||||||
"caddy.handle_path": "/ws",
|
|
||||||
"caddy.handle_path.reverse_proxy": "{{upstreams 9001}}",
|
|
||||||
"caddy.tls.dns": "cloudflare"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# caddy-docker-proxy automatically detects new container
|
# 2. mcmqtt spawns Docker container with automatic caddy labels:
|
||||||
# Adds route to Caddyfile: api-coord.mqtt.yourdomain.com
|
docker run -d \
|
||||||
# Issues wildcard certificate via Cloudflare DNS
|
--name mqtt-broker-customer-acme-prod \
|
||||||
# Result: Instant HTTPS routing with zero manual config!
|
--network caddy \
|
||||||
|
--label "caddy=acme.mqtt.yourdomain.com" \
|
||||||
|
--label "caddy.reverse_proxy={{upstreams 1883}}" \
|
||||||
|
--label "caddy.handle_path=/ws" \
|
||||||
|
--label "caddy.handle_path.reverse_proxy={{upstreams 9001}}" \
|
||||||
|
--label "caddy.tls.dns=cloudflare" \
|
||||||
|
python:3.11-slim uvx amqtt
|
||||||
|
|
||||||
|
# 3. caddy-docker-proxy automatically detects the new container
|
||||||
|
# 4. Generates Caddyfile configuration instantly:
|
||||||
|
# acme.mqtt.yourdomain.com {
|
||||||
|
# reverse_proxy mqtt-broker-customer-acme-prod:1883
|
||||||
|
# handle_path /ws {
|
||||||
|
# reverse_proxy mqtt-broker-customer-acme-prod:9001
|
||||||
|
# }
|
||||||
|
# tls {
|
||||||
|
# dns cloudflare
|
||||||
|
# }
|
||||||
|
# }
|
||||||
|
|
||||||
|
# 5. Result: https://acme.mqtt.yourdomain.com is LIVE with valid certificate!
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**Production Deployment Example:**
|
||||||
|
```bash
|
||||||
|
# Clone and deploy the complete stack
|
||||||
|
git clone https://github.com/your-org/mcmqtt-production-stack
|
||||||
|
cd mcmqtt-production-stack
|
||||||
|
|
||||||
|
# Configure your domain and Cloudflare
|
||||||
|
cp .env.example .env
|
||||||
|
# Edit .env with your settings
|
||||||
|
|
||||||
|
# Deploy production stack
|
||||||
|
make deploy
|
||||||
|
|
||||||
|
# Test the deployment
|
||||||
|
make test-deployment
|
||||||
|
|
||||||
|
# Spawn your first public broker
|
||||||
|
curl -X POST https://mqtt-control.yourdomain.com/api/brokers \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{
|
||||||
|
"name": "my-first-broker",
|
||||||
|
"public_hostname": "test.mqtt.yourdomain.com",
|
||||||
|
"websocket_port": 9001,
|
||||||
|
"auth_required": true
|
||||||
|
}'
|
||||||
|
|
||||||
|
# Result: https://test.mqtt.yourdomain.com is immediately accessible!
|
||||||
|
```
|
||||||
|
|
||||||
|
### ⚡ Auto-Labeling with `--transport http-streamable`
|
||||||
|
|
||||||
|
**Zero configuration Caddy integration!**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Traditional: Manual caddy labels
|
||||||
|
uvx mcmqtt --transport http --port 3000
|
||||||
|
# Requires manual caddy labels in docker-compose.yml
|
||||||
|
|
||||||
|
# Auto-magic: Automatic caddy labels
|
||||||
|
uvx mcmqtt --transport http-streamable --hostname mqtt-control.yourdomain.com
|
||||||
|
# Automatically adds all necessary caddy-docker-proxy labels!
|
||||||
|
```
|
||||||
|
|
||||||
|
**What `--transport http-streamable` Does:**
|
||||||
|
|
||||||
|
1. **Detects caddy-docker-proxy environment**
|
||||||
|
2. **Automatically adds container labels:**
|
||||||
|
```docker
|
||||||
|
--label "caddy=${HOSTNAME}"
|
||||||
|
--label "caddy.reverse_proxy={{upstreams ${PORT}}}"
|
||||||
|
--label "caddy.tls.dns=cloudflare" # If CLOUDFLARE_API_TOKEN detected
|
||||||
|
--label "caddy.handle_path=/ws" # For WebSocket support
|
||||||
|
```
|
||||||
|
3. **Configures FastMCP server for streaming responses**
|
||||||
|
4. **Enables real-time broker status updates via SSE**
|
||||||
|
|
||||||
|
**Environment-Based Auto-Configuration:**
|
||||||
|
```bash
|
||||||
|
# mcmqtt detects these environment variables:
|
||||||
|
CADDY_NETWORK=caddy # Join caddy network automatically
|
||||||
|
CLOUDFLARE_API_TOKEN=xxx # Enable DNS challenge for wildcard certs
|
||||||
|
DOMAIN=yourdomain.com # Use as base domain for spawned brokers
|
||||||
|
SSL_EMAIL=admin@yourdomain.com # Let's Encrypt certificate email
|
||||||
|
|
||||||
|
# Result: Zero manual configuration needed!
|
||||||
|
```
|
||||||
|
|
||||||
|
**Simplified Docker Compose:**
|
||||||
|
```yaml
|
||||||
|
services:
|
||||||
|
mcmqtt:
|
||||||
|
image: python:3.11-slim
|
||||||
|
command: uvx mcmqtt --transport http-streamable --hostname mqtt-control.${DOMAIN}
|
||||||
|
volumes:
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||||
|
networks:
|
||||||
|
- caddy
|
||||||
|
environment:
|
||||||
|
- DOMAIN=${DOMAIN}
|
||||||
|
- CADDY_NETWORK=caddy
|
||||||
|
- CLOUDFLARE_API_TOKEN=${CLOUDFLARE_API_TOKEN}
|
||||||
|
# No manual labels needed - all automatic!
|
||||||
|
```
|
||||||
|
|
||||||
|
**Benefits of http-streamable mode:**
|
||||||
|
- 🏷️ **Auto-labeling**: Caddy labels added automatically
|
||||||
|
- 📡 **Real-time updates**: Server-Sent Events for broker status
|
||||||
|
- 🔄 **Live monitoring**: Streaming broker health and metrics
|
||||||
|
- 🎯 **Zero config**: Environment-based auto-configuration
|
||||||
|
- 🚀 **Production ready**: Optimized for long-running deployments
|
||||||
|
|
||||||
### 🐳 Docker Socket Magic = Instant Infrastructure
|
### 🐳 Docker Socket Magic = Instant Infrastructure
|
||||||
|
|
||||||
**How mcmqtt + caddy-docker-proxy Works:**
|
**How mcmqtt + caddy-docker-proxy Works:**
|
||||||
|
Loading…
x
Reference in New Issue
Block a user