Add Docker build for browser mode with optimized 3-stage build, multi-platform support, comprehensive UI testing, one-click deployment, enterprise SSO integration, and biweekly CI pipeline (#934)
## 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>
This commit is contained in:
250
DOCKER.md
Normal file
250
DOCKER.md
Normal file
@@ -0,0 +1,250 @@
|
||||
# MQTT Explorer - Docker Browser Mode
|
||||
|
||||
Docker image for running MQTT Explorer in browser mode.
|
||||
|
||||
## Try It Now
|
||||
|
||||
[](https://labs.play-with-docker.com/?stack=https://raw.githubusercontent.com/thomasnordquist/MQTT-Explorer/master/docker-compose.yml)
|
||||
|
||||
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:
|
||||
|
||||
```bash
|
||||
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:
|
||||
|
||||
```yaml
|
||||
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:
|
||||
|
||||
```bash
|
||||
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!):**
|
||||
```bash
|
||||
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:
|
||||
|
||||
```bash
|
||||
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:
|
||||
|
||||
```bash
|
||||
docker run -v mqtt-explorer-data:/app/data ...
|
||||
```
|
||||
|
||||
## Building from Source
|
||||
|
||||
Build the Docker image locally:
|
||||
|
||||
```bash
|
||||
docker build -f Dockerfile.browser -t mqtt-explorer:local .
|
||||
```
|
||||
|
||||
Run the locally built image:
|
||||
|
||||
```bash
|
||||
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:
|
||||
|
||||
```bash
|
||||
docker inspect --format='{{.State.Health.Status}}' mqtt-explorer
|
||||
```
|
||||
|
||||
## Security Best Practices
|
||||
|
||||
1. **Use HTTPS in Production**: Put the container behind a reverse proxy (nginx, Traefik) with HTTPS
|
||||
2. **Set Strong Credentials**: Always set custom credentials via environment variables
|
||||
3. **Network Isolation**: Run in a private network when possible
|
||||
4. **Update Regularly**: Pull the latest image regularly for security updates
|
||||
|
||||
### Example with Nginx Reverse Proxy
|
||||
|
||||
```nginx
|
||||
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:
|
||||
```bash
|
||||
docker logs mqtt-explorer
|
||||
```
|
||||
|
||||
### Can't access the application
|
||||
|
||||
1. Verify the container is running: `docker ps`
|
||||
2. Check the port mapping: `docker port mqtt-explorer`
|
||||
3. Test connectivity: `curl http://localhost:3000`
|
||||
|
||||
### Authentication issues
|
||||
|
||||
1. Check generated credentials in logs: `docker logs mqtt-explorer`
|
||||
2. Verify environment variables: `docker inspect mqtt-explorer`
|
||||
3. 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:
|
||||
|
||||
```bash
|
||||
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 branch
|
||||
- `master` - Latest build from master branch
|
||||
- `beta` - Latest beta version
|
||||
- `release` - Latest release version
|
||||
- `master-<sha>` - Specific commit from master
|
||||
- `beta-<sha>` - Specific commit from beta
|
||||
- `release-<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:
|
||||
|
||||
[](https://labs.play-with-docker.com/?stack=https://raw.githubusercontent.com/thomasnordquist/MQTT-Explorer/master/docker-compose.yml)
|
||||
|
||||
- **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
|
||||
|
||||
[](https://cloud.digitalocean.com/apps/new?repo=https://github.com/thomasnordquist/MQTT-Explorer/tree/master&refcode=docker)
|
||||
|
||||
- Automatically detects Docker configuration
|
||||
- Managed platform with auto-scaling
|
||||
- Starting at $5/month
|
||||
|
||||
#### Koyeb
|
||||
|
||||
[](https://app.koyeb.com/deploy?type=docker&name=mqtt-explorer&image=ghcr.io/thomasnordquist/mqtt-explorer:latest&ports=3000;http;/)
|
||||
|
||||
- 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](LICENSE.md) file.
|
||||
Reference in New Issue
Block a user