## Docker Build for Browser Solution This PR creates a Docker build for the browser solution (MQTT Explorer server mode). ### Completed: - [x] Create a production Dockerfile for the browser solution (`Dockerfile.browser`) - **NEW**: 3-stage build for maximum optimization - **NEW**: Clean production dependency installation with `yarn --production` - **NEW**: Only compiled dist/ folder copied (no source code) - Alpine Linux base with Node.js 24 - Non-root user (UID 1001) for security - Health check endpoint with proper error handling - Proper signal handling with dumb-init - Production dependencies automatically filtered by yarn - [x] Apply Docker best practices (multi-stage build, minimal image, non-root user, .dockerignore) - Created comprehensive .dockerignore - **FIXED**: Removed events from .dockerignore (needed for build) - **NEW**: Optimized for smaller layers with combined RUN commands - **NEW**: Removed development dependencies from final image - Used alpine base image - [x] Create GitHub Actions workflow for building, publishing, and testing the Docker image - Builds for linux/amd64, linux/arm64, linux/arm/v7 - **FIXED**: Added tsconfig.json and events/** to workflow trigger paths - **FIXED**: Attestation now uses correct digest from build step output - **NEW**: Mosquitto MQTT broker service for integration testing - **NEW**: MQTT broker configurable via MQTT_BROKER_HOST and MQTT_BROKER_PORT environment variables - **NEW**: Full UI test suite runs against containerized application - Tests container startup, health check, HTTP response, data persistence - **NEW**: Image size reporting in workflow summary - Tests verify application works with MQTT broker - Publishes to GitHub Container Registry (ghcr.io/thomasnordquist/mqtt-explorer) - Includes build attestation for supply chain security - [x] Configure workflow to run on push and every two weeks via cron schedule - Runs on 1st and 15th of each month at 2:00 AM UTC - Also runs on push to master/beta/release branches when relevant files change - Manual trigger via workflow_dispatch - [x] Add comprehensive test suite - Basic smoke tests: startup, health check, HTTP response, data persistence - **NEW**: Full UI test suite (`test:browser`) runs against Docker container - **NEW**: Tests connect to configurable MQTT broker (default localhost:1883) - Tests execute with Mosquitto MQTT broker available for backend integration - Same comprehensive tests validate both Electron and browser modes - [x] Test organization and naming - **NEW**: Renamed `test:ui` to `test:electron` for Electron-specific tests - **NEW**: Added `test:browser` script for browser mode tests (runs same UI test suite) - **NEW**: Kept `test:ui` as backward-compatible alias - **NEW**: Renamed `ui-tests` workflow job to `electron-tests` for clarity - [x] Update documentation with Docker usage instructions - Created DOCKER.md with comprehensive Docker documentation - Updated README.md with Docker quick start - **UPDATED**: CI_CD.md now lists all 10 test steps accurately - **NEW**: Added one-click deployment options section - **NEW**: Added authentication modes documentation - [x] **NEW**: One-click deployment solutions - **NEW**: Created docker-compose.yml for easy deployment - **NEW**: Added Play with Docker (PWD) badge for instant browser-based demo - **NEW**: Added DigitalOcean App Platform deployment badge - **NEW**: Added Koyeb deployment badge - **NEW**: Comprehensive deployment options documentation in DOCKER.md - **NEW**: "Try It Now" section in README.md and DOCKER.md with PWD badge - [x] **NEW**: Enterprise authentication integration - **NEW**: Added `MQTT_EXPLORER_SKIP_AUTH` environment variable - **NEW**: Allows disabling built-in authentication for proxy-based auth (OAuth2 Proxy, Authelia, enterprise SSO) - **NEW**: Socket.IO emits `auth-status` event on connection with authentication state - **NEW**: Frontend receives auth status via Socket.IO and skips login dialog when disabled - **NEW**: Logout button hidden when authentication is disabled - **NEW**: Created AuthContext for managing authentication state across components - **NEW**: Comprehensive security warnings in documentation about using skip auth only behind trusted authentication proxies - **NEW**: Updated docker-compose.yml with commented example for proxy authentication - [x] Code review and security scan passed - Fixed health check to handle connection errors properly - Corrected cron schedule comment - No security vulnerabilities found - Fixed image tag naming consistency - Simplified dependency management - **FIXED**: Workflow trigger paths now include all build-affecting files - **FIXED**: Attestation digest reference corrected - **FIXED**: events directory included in Docker build context - **FIXED**: Mosquitto service properly configured for integration testing - **FIXED**: MQTT broker connection now configurable for flexible testing environments - **IMPROVED**: Auth status now communicated via Socket.IO for better real-time synchronization - [x] Rename image to ghcr.io/thomasnordquist/mqtt-explorer (removed -browser suffix) - [x] Add multi-platform support for Raspberry Pi - linux/arm64 (Raspberry Pi 3/4/5) - linux/arm/v7 (Raspberry Pi 2/3) - [x] Upgrade to Node.js 24 (matching project requirements) - [x] **NEW**: Optimize Docker image for minimal size - Only production dependencies (no devDependencies) - No backend source code (only compiled JavaScript) - Removed build tools and dev dependencies - Combined layers for smaller image - **Image size reported in workflow summary** - [x] **NEW**: Fix webpack build configuration - **Enable minification** for production builds (was disabled) - **Update Material-UI references** from @material-ui to @mui - Fix vendor chunking to include @mui and @emotion packages - Reduces bundle size and fixes missing component issues ### Docker Image Features: - **Base**: Alpine Linux with Node.js 24 - **Size**: Reported automatically in workflow summary - **Platforms**: amd64, arm64, arm/v7 (Raspberry Pi support) - **Security**: Non-root user, minimal attack surface - **Reliability**: Health checks, graceful shutdown - **Persistence**: Data volume at `/app/data` - **Registry**: ghcr.io/thomasnordquist/mqtt-explorer - **Runtime deps**: Only production dependencies (automatically filtered) - **Frontend**: Minified webpack bundles with proper vendor splitting - **Testing**: Full UI test suite with configurable MQTT broker integration - **One-Click Deploy**: Play with Docker, DigitalOcean, Koyeb - **Enterprise Ready**: Optional authentication bypass for proxy-based SSO ### Available Tags: - `latest` - Latest stable from master - `master`, `beta`, `release` - Latest from each branch - `<branch>-<sha>` - Specific commits ### Authentication Options: 1. **Standard Mode** (default): Built-in username/password authentication - Set credentials via `MQTT_EXPLORER_USERNAME` and `MQTT_EXPLORER_PASSWORD` environment variables 2. **Skip Authentication Mode**: Set `MQTT_EXPLORER_SKIP_AUTH=true` for proxy-based auth - Use only behind trusted authentication proxies (OAuth2 Proxy, Authelia, enterprise SSO) - Socket.IO automatically informs frontend about auth status on connection - Frontend skips login dialog and logout button is hidden when authentication is disabled - ⚠️ **Security Warning**: Only use in environments with external authentication protection ### One-Click Deployment: Try MQTT Explorer instantly without installation: - **Play with Docker**: Free browser-based demo (click badge in README.md or DOCKER.md) - **DigitalOcean**: Deploy to managed platform starting at $5/month - **Koyeb**: Deploy to global edge network with free tier ### Security Summary: - CodeQL scan passed with no vulnerabilities - Docker image runs as non-root user (UID 1001) - Multi-stage build reduces attack surface - Health check includes proper error handling - Minimal runtime dependencies reduce vulnerability exposure - Full UI test suite validates application functionality - Build attestation with correct digest reference - MQTT broker integration tested with configurable connection via environment variables - Optional authentication bypass for enterprise SSO integration (with comprehensive security warnings) - Auth status communicated via Socket.IO for real-time synchronization <!-- START COPILOT ORIGINAL PROMPT --> <details> <summary>Original prompt</summary> > > ---- > > *This section details on the original issue you should resolve* > > <issue_title>create a docker build for the browser solution</issue_title> > <issue_description>Create a docker build for amd64, that ships with a minimal image including nodes. Apply best practices and create a test workflow that builds it , publishes it and tests the built image. Build it every two weeks</issue_description> > > ## Comments on the Issue (you are @copilot in this section) > > <comments> > </comments> > </details> <!-- START COPILOT CODING AGENT SUFFIX --> - Fixes thomasnordquist/MQTT-Explorer#933 <!-- START COPILOT CODING AGENT TIPS --> --- 💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more [Copilot coding agent tips](https://gh.io/copilot-coding-agent-tips) in the docs. --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: thomasnordquist <7721625+thomasnordquist@users.noreply.github.com> Co-authored-by: Thomas Nordquist <thomasnordquist@users.noreply.github.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
7.6 KiB
MQTT Explorer - Docker Browser Mode
Docker image for running MQTT Explorer in browser mode.
Try It Now
Click the badge above to instantly try MQTT Explorer in your browser using Play with Docker (requires free Docker Hub account).
Quick Start
Using Pre-built Image
Pull and run the latest image from GitHub Container Registry:
docker pull ghcr.io/thomasnordquist/mqtt-explorer:latest
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
Access the application at http://localhost:3000
Using Docker Compose
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
volumes:
mqtt-explorer-data:
Then run:
docker-compose up -d
Environment Variables
| Variable | Required | Default | Description |
|---|---|---|---|
MQTT_EXPLORER_USERNAME |
No | Generated | Username for authentication |
MQTT_EXPLORER_PASSWORD |
No | Generated | Password for authentication |
MQTT_EXPLORER_SKIP_AUTH |
No | false |
Set to true to disable authentication (use only behind a secure proxy!) |
PORT |
No | 3000 |
Port the server listens on |
ALLOWED_ORIGINS |
No | * |
Comma-separated list of allowed CORS origins |
NODE_ENV |
No | - | Set to production for production deployments |
Authentication Modes
Standard Mode (Default):
- Requires username and password for access
- Credentials can be set via environment variables or auto-generated
- Auto-generated credentials are logged on first startup and saved to
/app/data/credentials.json
Skip Authentication Mode (Use with caution!):
docker run -d -p 3000:3000 \
-e MQTT_EXPLORER_SKIP_AUTH=true \
ghcr.io/thomasnordquist/mqtt-explorer:latest
⚠️ WARNING: When MQTT_EXPLORER_SKIP_AUTH=true, the application is completely open without any authentication. This should only be used when MQTT Explorer is deployed behind a secure authentication proxy (e.g., OAuth2 Proxy, Authelia, Nginx with auth_request) or in a trusted private network.
Recommended use case: Integration with enterprise SSO systems where authentication is handled by a reverse proxy.
Note: If credentials are not provided and auth is not skipped, they will be auto-generated and stored in /app/data/credentials.json. Check the container logs to see the generated credentials:
docker logs mqtt-explorer
Data Persistence
The container stores data in /app/data, including:
- User credentials (
credentials.json) - Connection settings (
settings.json) - Uploaded certificates (
certificates/) - File uploads (
uploads/)
Mount a volume to persist data across container restarts:
docker run -v mqtt-explorer-data:/app/data ...
Building from Source
Build the Docker image locally:
docker build -f Dockerfile.browser -t mqtt-explorer:local .
Run the locally built image:
docker run -d \
-p 3000:3000 \
-e MQTT_EXPLORER_USERNAME=admin \
-e MQTT_EXPLORER_PASSWORD=secret \
mqtt-explorer:local
Health Check
The container includes a health check that runs every 30 seconds. Check the health status:
docker inspect --format='{{.State.Health.Status}}' mqtt-explorer
Security Best Practices
- Use HTTPS in Production: Put the container behind a reverse proxy (nginx, Traefik) with HTTPS
- Set Strong Credentials: Always set custom credentials via environment variables
- Network Isolation: Run in a private network when possible
- Update Regularly: Pull the latest image regularly for security updates
Example with Nginx Reverse Proxy
server {
listen 443 ssl http2;
server_name mqtt-explorer.example.com;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
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;
}
}
Troubleshooting
Container won't start
Check the logs:
docker logs mqtt-explorer
Can't access the application
- Verify the container is running:
docker ps - Check the port mapping:
docker port mqtt-explorer - Test connectivity:
curl http://localhost:3000
Authentication issues
- Check generated credentials in logs:
docker logs mqtt-explorer - Verify environment variables:
docker inspect mqtt-explorer - Reset credentials by removing the data volume and restarting
Permission issues
The container runs as a non-root user (UID 1001). If mounting host directories, ensure they're writable:
chown -R 1001:1001 /path/to/host/data
docker run -v /path/to/host/data:/app/data ...
Available Tags
latest- Latest stable version from the master branchmaster- Latest build from master branchbeta- Latest beta versionrelease- Latest release versionmaster-<sha>- Specific commit from masterbeta-<sha>- Specific commit from betarelease-<sha>- Specific commit from release
Supported Platforms
The Docker image is built for multiple architectures:
linux/amd64- x86-64 (standard PCs, servers)linux/arm64- ARM 64-bit (Raspberry Pi 3/4/5, Apple Silicon)linux/arm/v7- ARM 32-bit (Raspberry Pi 2/3)
One-Click Deployment Options
Play with Docker (Free)
Try MQTT Explorer instantly in your browser without installing anything:
- No installation required - Runs entirely in your browser
- Free to use - Requires only a Docker Hub account
- Perfect for demos - Great for testing and demonstrations
- 4-hour sessions - Sessions automatically expire after 4 hours
Cloud Platforms
Deploy MQTT Explorer to various cloud platforms with one click:
DigitalOcean App Platform
- Automatically detects Docker configuration
- Managed platform with auto-scaling
- Starting at $5/month
Koyeb
- Deploy directly from Docker image
- Global edge network
- Free tier available
Note: Remember to set the environment variables MQTT_EXPLORER_USERNAME and MQTT_EXPLORER_PASSWORD when deploying to cloud platforms.
License
See the main LICENSE.md file.
