Skip to main content
MQTT Explorer can be deployed as a Docker container, providing a web-based interface accessible from any browser. This is ideal for server deployments, remote access, and team collaboration.

Quick Start

1

Pull the Image

Pull the latest pre-built image from GitHub Container Registry:
docker pull ghcr.io/thomasnordquist/mqtt-explorer:latest
2

Run the Container

Start MQTT Explorer with basic authentication:
docker run -d \
  -p 3000:3000 \
  -e MQTT_EXPLORER_USERNAME=admin \
  -e MQTT_EXPLORER_PASSWORD=your_secure_password \
  -v mqtt-explorer-data:/app/data \
  --name mqtt-explorer \
  ghcr.io/thomasnordquist/mqtt-explorer:latest
3

Access Application

Open your browser to http://localhost:3000 and log in with your credentials.

Docker Compose

For production deployments, use Docker Compose for better configuration management:

Basic Setup

Create a docker-compose.yml file:
version: '3.8'

services:
  mqtt-explorer:
    image: ghcr.io/thomasnordquist/mqtt-explorer:latest
    ports:
      - "3000:3000"
    environment:
      - MQTT_EXPLORER_USERNAME=admin
      - MQTT_EXPLORER_PASSWORD=your_secure_password
      - PORT=3000
    volumes:
      - mqtt-explorer-data:/app/data
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "node", "-e", "require('http').get('http://localhost:3000', (r) => process.exit(r.statusCode === 200 ? 0 : 1)).on('error', () => process.exit(1))"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s

volumes:
  mqtt-explorer-data:
Start the application:
docker-compose up -d

With AI Assistant

Enable the AI Assistant feature by adding LLM configuration:
version: '3.8'

services:
  mqtt-explorer:
    image: ghcr.io/thomasnordquist/mqtt-explorer:latest
    ports:
      - "3000:3000"
    environment:
      - MQTT_EXPLORER_USERNAME=admin
      - MQTT_EXPLORER_PASSWORD=your_secure_password
      # AI Assistant Configuration
      - LLM_PROVIDER=openai
      - OPENAI_API_KEY=sk-proj-xxxxxxxxxxxxxxxxxxxx
      - LLM_NEIGHBORING_TOPICS_TOKEN_LIMIT=500
    volumes:
      - mqtt-explorer-data:/app/data
    restart: unless-stopped

volumes:
  mqtt-explorer-data:
API keys remain server-side only and are never transmitted to the frontend. The backend proxies all LLM requests via secure WebSocket RPC.

Environment Variables

Authentication

MQTT_EXPLORER_USERNAME
string
Username for web interface authentication. If not provided, a random username will be generated.
MQTT_EXPLORER_PASSWORD
string
Password for web interface authentication. If not provided, a random password will be generated and logged.
MQTT_EXPLORER_SKIP_AUTH
boolean
default:"false"
Set to true to disable authentication completely.
Only use this when MQTT Explorer is deployed behind a secure authentication proxy (OAuth2 Proxy, Authelia, Nginx auth_request) or in a trusted private network.

Server Configuration

PORT
number
default:"3000"
Port the server listens on inside the container.
ALLOWED_ORIGINS
string
default:"*"
Comma-separated list of allowed CORS origins. In production, specify exact origins instead of using *.
ALLOWED_ORIGINS=https://mqtt.example.com,https://mqtt-dev.example.com
NODE_ENV
string
Set to production for production deployments. This enables production optimizations and security features.

Security Headers

UPGRADE_INSECURE_REQUESTS
boolean
default:"false"
Set to true to enable Content Security Policy upgrade-insecure-requests directive.
Only use when deployed behind an HTTPS reverse proxy (nginx, Traefik, etc.) with valid SSL certificates. This upgrades all HTTP requests to HTTPS and will break direct HTTP access.
X_FRAME_OPTIONS
boolean
default:"false"
Set to true to enable X-Frame-Options: SAMEORIGIN header to prevent clickjacking.
This disables iframe embedding when enabled.

AI Assistant Configuration

LLM_PROVIDER
string
default:"openai"
AI provider to use: openai or gemini
OPENAI_API_KEY
string
OpenAI API key for AI Assistant. Required when LLM_PROVIDER=openai.
GEMINI_API_KEY
string
Google Gemini API key for AI Assistant. Required when LLM_PROVIDER=gemini.
LLM_API_KEY
string
Generic API key that works with either provider. Alternative to provider-specific keys.
LLM_NEIGHBORING_TOPICS_TOKEN_LIMIT
number
default:"500"
Token limit for neighboring topics context in AI queries. Increase for better device relationship detection.

Data Persistence

The container stores data in /app/data, including:
  • credentials.json - User credentials (auto-generated if not provided)
  • settings.json - Connection settings and preferences
  • certificates/ - Uploaded SSL/TLS certificates
  • uploads/ - File uploads

Mounting a Volume

Use a named volume for automatic management:
docker run -v mqtt-explorer-data:/app/data \
  ghcr.io/thomasnordquist/mqtt-explorer:latest

Mounting a Host Directory

For direct access to data files:
# Create directory with correct permissions
mkdir -p /path/to/mqtt-explorer-data
chown -R 1001:1001 /path/to/mqtt-explorer-data

# Run container
docker run -v /path/to/mqtt-explorer-data:/app/data \
  ghcr.io/thomasnordquist/mqtt-explorer:latest
The container runs as non-root user (UID 1001). Host directories must be owned by this UID or be world-writable.

Building from Source

1

Clone Repository

git clone https://github.com/thomasnordquist/MQTT-Explorer.git
cd MQTT-Explorer
2

Build Docker Image

docker build -f Dockerfile.browser -t mqtt-explorer:local .
The build uses a multi-stage Dockerfile:
  1. Builder stage - Compiles TypeScript and builds frontend with webpack
  2. Production stage - Creates minimal image with only runtime dependencies
3

Run Local Build

docker run -d \
  -p 3000:3000 \
  -e MQTT_EXPLORER_USERNAME=admin \
  -e MQTT_EXPLORER_PASSWORD=secret \
  mqtt-explorer:local

Multi-Architecture Builds

Build for multiple architectures using buildx:
# Create and use a new builder
docker buildx create --use

# Build for multiple platforms
docker buildx build \
  --platform linux/amd64,linux/arm64,linux/arm/v7 \
  -f Dockerfile.browser \
  -t mqtt-explorer:multi-arch \
  --push .

Supported Platforms

The official Docker images support multiple architectures:
PlatformArchitectureUse Case
linux/amd64x86-64Standard PCs, servers, cloud instances
linux/arm64ARM 64-bitRaspberry Pi 3/4/5, Apple Silicon, AWS Graviton
linux/arm/v7ARM 32-bitRaspberry Pi 2/3 (32-bit OS)
Docker automatically selects the correct architecture for your platform.

Available Tags

Choose from multiple image tags based on your stability requirements:
  • latest - Latest stable version from master branch
  • master - Latest build from master branch
  • beta - Latest beta version
  • release - Latest official release
  • master-<sha> - Specific commit from master (e.g., master-abc123)
  • beta-<sha> - Specific commit from beta
  • release-<sha> - Specific commit from release

Production Deployment

HTTPS with Nginx Reverse Proxy

For production, deploy behind a reverse proxy with SSL/TLS:
server {
    listen 443 ssl http2;
    server_name mqtt-explorer.example.com;

    ssl_certificate /path/to/cert.pem;
    ssl_certificate_key /path/to/key.pem;

    # WebSocket support
    location / {
        proxy_pass http://localhost:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

With Traefik

Use Traefik for automatic SSL certificate management:
version: '3.8'

services:
  mqtt-explorer:
    image: ghcr.io/thomasnordquist/mqtt-explorer:latest
    environment:
      - MQTT_EXPLORER_USERNAME=admin
      - MQTT_EXPLORER_PASSWORD=${MQTT_PASSWORD}
      - NODE_ENV=production
    volumes:
      - mqtt-explorer-data:/app/data
    restart: unless-stopped
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.mqtt-explorer.rule=Host(`mqtt-explorer.example.com`)"
      - "traefik.http.routers.mqtt-explorer.entrypoints=websecure"
      - "traefik.http.routers.mqtt-explorer.tls.certresolver=letsencrypt"
      - "traefik.http.services.mqtt-explorer.loadbalancer.server.port=3000"

volumes:
  mqtt-explorer-data:

networks:
  default:
    external:
      name: traefik

One-Click Deployment

Play with Docker

Try MQTT Explorer instantly in your browser. Free, no installation required. Sessions last 4 hours.

DigitalOcean App Platform

Deploy with managed platform and auto-scaling. Starting at $5/month.

Koyeb

Deploy on global edge network. Free tier available.

Railway

Click “Deploy on Railway” button from the GitHub repository.
Remember to set MQTT_EXPLORER_USERNAME and MQTT_EXPLORER_PASSWORD environment variables when deploying to cloud platforms.

Health Checks

The container includes built-in health checks that run every 30 seconds:
# Check health status
docker inspect --format='{{.State.Health.Status}}' mqtt-explorer

# View health check logs
docker inspect --format='{{json .State.Health}}' mqtt-explorer | jq
Health check configuration:
  • Interval: 30 seconds
  • Timeout: 10 seconds
  • Retries: 3
  • Start Period: 40 seconds (allows time for startup)

Troubleshooting

Check container logs for errors:
docker logs mqtt-explorer
Common issues:
  • Port 3000 already in use: Change port mapping -p 8080:3000
  • Permission errors: Ensure data volume is writable by UID 1001
  • Out of memory: Increase Docker memory limits
Verify the container is running:
# Check container status
docker ps

# Check port mapping
docker port mqtt-explorer

# Test connectivity
curl http://localhost:3000
Check firewall rules allow connections to port 3000.
Check generated credentials in logs:
docker logs mqtt-explorer 2>&1 | grep -A 5 "Generated new credentials"
Or inspect the stored credentials:
docker exec mqtt-explorer cat /app/data/credentials.json
Reset credentials by removing the volume and restarting:
docker-compose down -v
docker-compose up -d
The container runs as UID 1001. Ensure host directories have correct ownership:
sudo chown -R 1001:1001 /path/to/host/data
Or make the directory world-writable (less secure):
chmod 777 /path/to/host/data
Ensure your reverse proxy properly handles WebSocket upgrades:
# Required for WebSocket support
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
Check browser console for connection errors.

Security Best Practices

1

Use HTTPS in Production

Always deploy behind a reverse proxy with SSL/TLS certificates. Never expose the container directly to the internet over HTTP.
2

Set Strong Credentials

Use environment variables to set strong, unique passwords:
# Generate a random password
openssl rand -base64 32
3

Configure CORS Properly

In production, specify exact origins instead of using wildcard:
environment:
  - ALLOWED_ORIGINS=https://mqtt-explorer.example.com
4

Keep Images Updated

Regularly pull and deploy the latest image for security updates:
docker-compose pull
docker-compose up -d
5

Use Docker Secrets for Sensitive Data

In Docker Swarm, use secrets instead of environment variables:
services:
  mqtt-explorer:
    secrets:
      - mqtt_password

secrets:
  mqtt_password:
    external: true

Next Steps

Browser Mode Guide

Learn about browser mode architecture and features

Configuration

Configure MQTT connections and advanced settings