Files
mqtt-explorer/CI_CD.md
Copilot 2c147a92ad 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>
2025-12-22 21:06:35 +01:00

5.9 KiB

CI/CD Pipeline Documentation

Overview

MQTT Explorer uses GitHub Actions for continuous integration and testing. The pipeline tests both Electron (desktop) and browser modes.

Workflows

Test Workflow (.github/workflows/tests.yml)

This workflow runs on pull requests to master, beta, and release branches.

Docker Browser Build Workflow (.github/workflows/docker-browser.yml)

This workflow builds and publishes a Docker image for the browser mode.

Triggers:

  • Push to master, beta, or release branches (when relevant files change)
  • Schedule: Runs every two weeks (1st and 15th of each month at 2:00 AM UTC)
  • Manual trigger via workflow_dispatch

Platforms:

  • linux/amd64 (x86-64)
  • linux/arm64 (Raspberry Pi 3/4/5, Apple Silicon)
  • linux/arm/v7 (Raspberry Pi 2/3)

Image Registry: GitHub Container Registry (ghcr.io/thomasnordquist/mqtt-explorer)

Tags:

  • latest - Latest build from master branch
  • master - Latest build from master
  • beta - Latest build from beta branch
  • release - Latest build from release branch
  • <branch>-<sha> - Specific commit builds

Steps:

  1. Build Docker image with multi-stage build
  2. Test basic startup with test credentials
  3. Test health check
  4. Verify HTTP response
  5. Test data directory creation
  6. Check Docker image size
  7. Start container for frontend tests
  8. Test frontend bundles (app.bundle.js, vendors.bundle.js)
  9. Push image to GitHub Container Registry
  10. Generate build attestation for supply chain security

Image Features:

  • Multi-stage build for minimal size
  • Alpine Linux base with Node.js 24 (~200MB final image)
  • Multi-platform support (amd64, arm64, arm/v7)
  • Non-root user (UID 1001)
  • Health check endpoint
  • Proper signal handling with dumb-init
  • Persistent data volume at /app/data

Test Workflow (.github/workflows/tests.yml)

This workflow runs on pull requests to master, beta, and release branches.

Jobs

1. test - Electron Mode Tests

Tests the traditional Electron desktop application:

  • Environment: Custom Docker container (ghcr.io/thomasnordquist/mqtt-explorer-ui-tests:latest)
  • Steps:
    1. Install dependencies with frozen lockfile
    2. Build the Electron application
    3. Run unit tests (app + backend)
    4. Run UI tests with video recording
    5. Upload test video to S3
    6. Display test results in GitHub summary

Artifacts: UI test video (GIF format) uploaded to S3

2. test-browser - Browser Mode Tests

Tests the new browser/server mode:

  • Environment: Ubuntu latest with Node.js 20
  • Services:
    • Mosquitto MQTT Broker: Eclipse Mosquitto v2 on port 1883
      • Health checks enabled
      • Anonymous connections allowed
  • Steps:
    1. Setup Node.js 20
    2. Install dependencies
    3. Build browser mode (yarn build:server)
    4. Run unit tests (app + backend)
    5. Start server in background with test credentials
    6. Wait for server to be ready
    7. Run browser smoke tests
    8. Clean up server process

Environment Variables:

  • MQTT_EXPLORER_USERNAME=test
  • MQTT_EXPLORER_PASSWORD=test123
  • PORT=3000

Test Commands

The following npm scripts are used in CI/CD:

# Unit tests
yarn test              # Run all tests (app + backend)
yarn test:app          # Frontend tests only
yarn test:backend      # Backend tests only

# Build
yarn build             # Build Electron mode
yarn build:server      # Build browser mode

# UI Tests (Electron only)
yarn ui-test           # Run UI tests with video recording

Adding New Tests

For Electron Mode

Add tests to the test job. UI tests should be added to the test suite that yarn ui-test runs.

For Browser Mode

Browser-specific tests should:

  1. Use the pre-configured Mosquitto service
  2. Connect to mqtt://mosquitto:1883
  3. Test server endpoints at http://localhost:3000

Example:

- name: Browser Integration Test
  run: |
    # Test MQTT connection through server
    curl -X POST http://localhost:3000/api/test

Local Testing

Docker Browser Mode

# Build the image locally (for your platform)
docker build -f Dockerfile.browser -t mqtt-explorer:local .

# Build for specific platform (e.g., Raspberry Pi)
docker buildx build --platform linux/arm64 -f Dockerfile.browser -t mqtt-explorer:local-arm64 .

# Run the container
docker run -d \
  -p 3000:3000 \
  -e MQTT_EXPLORER_USERNAME=test \
  -e MQTT_EXPLORER_PASSWORD=test123 \
  mqtt-explorer:local

# Test the server
curl http://localhost:3000

# Check logs
docker logs <container-id>

# Stop and remove
docker stop <container-id>
docker rm <container-id>

See DOCKER.md for complete documentation.

Electron Mode

yarn build
yarn test
yarn ui-test

Browser Mode

# Start Mosquitto in Docker
docker run -d -p 1883:1883 eclipse-mosquitto:2

# Build and test
yarn build:server
yarn test

# Start server
MQTT_EXPLORER_USERNAME=test MQTT_EXPLORER_PASSWORD=test123 yarn start:server

# Run manual tests
curl http://localhost:3000

GitHub Codespaces / Devcontainer

The repository includes a devcontainer configuration that automatically sets up:

  • Node.js 20
  • MQTT broker (Mosquitto)
  • All development dependencies
  • Port forwarding for development

See .devcontainer/README.md for details.

Troubleshooting

Browser Tests Failing

  1. Server won't start: Check if port 3000 is already in use
  2. MQTT connection fails: Ensure Mosquitto service is healthy
  3. Timeout errors: Increase timeout in "Wait for Server" step

Electron Tests Failing

  1. UI tests timeout: Check if the Docker container has display access
  2. Build fails: Verify all dependencies are in yarn.lock

Future Improvements

  • Add E2E browser tests with Playwright
  • Test WebSocket connections in browser mode
  • Add performance benchmarks
  • Test with different MQTT broker versions
  • Add security scanning for browser mode