This documentation is part of the "Projects with Books" initiative at zenOSmosis.
The source code for this project is available on GitHub.
CI/CD and Automation
Loading…
CI/CD and Automation
Relevant source files
Purpose and Scope
This document describes the automated testing and documentation build systems that ensure code quality and maintain up-to-date documentation for the Docker MQTT Mosquitto Cloudflare Tunnel system.
The system implements two distinct automation pipelines:
- Continuous Integration Pipeline - Validates that the Mosquitto service can successfully start on every commit
- Documentation Build Pipeline - Generates and deploys wiki documentation to GitHub Pages
This page is organized into three main sections:
- Continuous Integration (Section 5.1) - Details the automated testing workflow
- Documentation Pipeline (Section 5.2) - Explains the documentation generation and deployment process
- Version Control Best Practices (Section 5.3) - Covers Git workflow and secret management in the context of CI/CD
For general system setup, see page 2 (Getting Started). For component details, see page 3 (Components).
Sources: .github/workflows/ci.yml, .github/workflows/build-docs.yml, .gitignore
Automation Pipeline Overview
The system uses GitHub Actions to automate quality assurance and documentation maintenance. Both pipelines execute in isolated GitHub-hosted runners and operate independently.
Pipeline Comparison
| Aspect | CI Pipeline | Documentation Pipeline |
|---|---|---|
| Workflow File | .github/workflows/ci.yml | .github/workflows/build-docs.yml |
| Trigger | Push or PR to main | Weekly schedule + manual dispatch |
| Runner | ubuntu-latest | ubuntu-latest |
| Primary Action | Test service startup | Generate and deploy docs |
| Duration | ~2 minutes | ~5 minutes |
| External Dependencies | Docker Compose | DeepWiki, GitHub Pages |
| Failure Impact | Blocks merge | Does not block development |
Sources: .github/workflows/ci.yml, .github/workflows/build-docs.yml
Automation Architecture
Diagram: GitHub Actions Pipeline Architecture
This diagram illustrates the two independent automation pipelines. The CI pipeline .github/workflows/ci.yml:1-43 executes on code changes, while the documentation pipeline .github/workflows/build-docs.yml:1-81 runs on a weekly schedule. Both use GitHub-hosted runners but have different trigger mechanisms and purposes.
Sources: .github/workflows/ci.yml, .github/workflows/build-docs.yml
5.1 Continuous Integration
The CI pipeline validates that the Mosquitto MQTT broker can successfully start in a Docker environment. This automated test runs on every push to main and on all pull requests targeting main.
Workflow Configuration
The workflow is defined in .github/workflows/ci.yml:1-43 with the following key elements:
Trigger Configuration .github/workflows/ci.yml:3-9:
Job Definition .github/workflows/ci.yml:11-13:
- Job Name:
test-mosquitto - Runner:
ubuntu-latest - Purpose: Validate Mosquitto container can start and reach running state
CI Execution Steps
| Step | Action | Purpose | Exit Condition |
|---|---|---|---|
| 1. Checkout | actions/checkout@v2 | Clone repository | Always succeeds |
| 2. Setup | apt-get install docker-compose | Install Docker Compose | Package installation complete |
| 3. Start Service | docker-compose up -d mosquitto | Launch Mosquitto container | Container created |
| 4. Health Check | Poll container status | Verify running state | Running or timeout (100s) |
| 5. Teardown | docker-compose down | Clean up resources | Always executes |
Health Check Mechanism
Diagram: Health Check Loop Logic
The health check loop .github/workflows/ci.yml:28-39 implements a polling strategy with bounded retry:
This bash loop:
- Executes up to 10 iterations
- Uses
docker inspectto query container state - Checks if status contains “running”
- Waits 10 seconds between attempts
- Fails after 100 seconds total (10 × 10s)
Sources: .github/workflows/ci.yml:28-39
Why Only Mosquitto Is Tested
The CI pipeline starts only the mosquitto service, not the cloudflared service .github/workflows/ci.yml25:
Rationale:
- The
cloudflaredcontainer requiresCLOUDFLARE_TUNNEL_TOKENenvironment variable - This token is a secret that cannot be exposed in public CI logs
- The
mosquittoservice has no external dependencies and can run in isolation - Starting Mosquitto validates the core MQTT broker functionality
The docker-compose.yml file docker-compose.yml:4-9 defines mosquitto as an independent service that doesn’t depend on cloudflared, enabling this isolated testing approach.
Sources: .github/workflows/ci.yml:25, docker-compose.yml:4-9
Failure Scenarios
| Failure Type | Symptom | Likely Cause | CI Outcome |
|---|---|---|---|
| Container won’t start | Exits before 100s | Invalid mosquitto.conf syntax | Exit 1, workflow fails |
| Container starts then crashes | Status changes from running | Configuration error (port conflict, permissions) | Exit 1, workflow fails |
| Timeout | Never reaches running state | Resource constraints, slow pull | Exit 1, workflow fails |
| Teardown failure | docker-compose down fails | Docker daemon issue | Step fails, workflow fails |
When the CI workflow fails, it blocks pull request merges, preventing broken configurations from entering the main branch.
Sources: .github/workflows/ci.yml:28-42
5.2 Documentation Pipeline
The documentation pipeline automatically generates and deploys technical documentation to GitHub Pages. It uses the DeepWiki documentation generation system to create an mdBook-formatted static site from the repository’s codebase.
Workflow Configuration
The workflow is defined in .github/workflows/build-docs.yml:1-81 with distinct build and deploy jobs.
Trigger Configuration .github/workflows/build-docs.yml:3-7:
The pipeline executes in two scenarios:
- Scheduled: Every Sunday at 00:00 UTC via cron schedule
- Manual: Triggered through GitHub UI via
workflow_dispatch
Permissions .github/workflows/build-docs.yml:9-12:
These permissions enable:
- Reading repository contents
- Writing to GitHub Pages deployment
- Generating OIDC tokens for secure deployment
Build Job
The build job .github/workflows/build-docs.yml:19-69 performs documentation generation:
Diagram: Documentation Build Job Flow
Step 1: Repository Resolution
.github/workflows/build-docs.yml:25-52 determines which repository to document:
This logic allows manual workflow dispatch to specify a different repository, defaulting to the current repository (github.repository context variable).
Step 2: Title Generation
.github/workflows/build-docs.yml:37-47 generates the documentation book title:
For this repository, the generated title would be: "docker-mqtt-mosquitto-cloudflare-tunnel Documentation"
Step 3: DeepWiki Generation
.github/workflows/build-docs.yml:59-64 invokes the DeepWiki documentation generator:
The jzombie/deepwiki-to-mdbook action:
- Analyzes the repository structure
- Generates markdown documentation pages
- Creates an mdBook configuration
- Outputs static HTML to
./output/book
Step 4: Artifact Upload
.github/workflows/build-docs.yml:66-69 uploads the generated documentation:
This creates a GitHub Actions artifact containing the compiled mdBook site, which is consumed by the deploy job.
Sources: .github/workflows/build-docs.yml:19-69
Deploy Job
The deploy job .github/workflows/build-docs.yml:71-81 publishes documentation to GitHub Pages:
Diagram: Documentation Deploy Job Flow
The deploy job configuration .github/workflows/build-docs.yml:71-80:
Key aspects:
- Dependency:
needs: buildensures build completes first - Environment: Publishes to
github-pagesenvironment - Output:
page_urlprovides the live documentation URL - Idempotency: Overwrites existing GitHub Pages deployment
Sources: .github/workflows/build-docs.yml:71-81
Concurrency Control
.github/workflows/build-docs.yml:14-16 prevents concurrent documentation builds:
This configuration:
- Groups all Pages deployments under single concurrency group
- Queues new runs instead of canceling in-progress deployments
- Prevents race conditions in GitHub Pages publishing
Sources: .github/workflows/build-docs.yml:14-16
Documentation Update Frequency
The weekly schedule ensures documentation stays current without excessive CI usage:
| Update Trigger | Frequency | Purpose |
|---|---|---|
| Scheduled | Weekly (Sunday 00:00 UTC) | Regular refresh |
| Manual | On-demand via UI | Immediate update after major changes |
| Automatic | Never on push | Prevents CI overload |
Manual triggering is accessible via: Actions → Build and Deploy Documentation → Run workflow
Sources: .github/workflows/build-docs.yml:3-7
5.3 Version Control Best Practices
The repository implements strict separation between public configuration and sensitive secrets to prevent credential leakage in version control.
Gitignore Configuration
The .gitignore file .gitignore:1-2 enforces this separation:
.env
data/*
Rationale:
| Excluded Path | Type | Reason | Alternative |
|---|---|---|---|
.env | Secret file | Contains CLOUDFLARE_TUNNEL_TOKEN | .env.sample provides template |
data/* | Runtime directory | Mosquitto persistent storage | Created automatically by container |
Secret Management Pattern
Diagram: Secret Management Flow in Version Control
This diagram shows how secrets flow from Cloudflare Dashboard to Docker containers without entering version control. The .gitignore file .gitignore1 acts as a security boundary.
Sources: .gitignore:1-2
Tracked vs Untracked Files
| File Path | Version Controlled | Contains Secrets | Purpose |
|---|---|---|---|
.env.sample | ✓ Yes | ✗ No | Documents required variables |
.env | ✗ No | ✓ Yes | Stores CLOUDFLARE_TUNNEL_TOKEN |
docker-compose.yml | ✓ Yes | ✗ No | References ${CLOUDFLARE_TUNNEL_TOKEN} variable |
mosquitto.conf | ✓ Yes | ✗ No | Public broker configuration |
.github/workflows/ci.yml | ✓ Yes | ✗ No | CI pipeline definition |
.github/workflows/build-docs.yml | ✓ Yes | ✗ No | Documentation pipeline |
data/* | ✗ No | ⚠ Maybe | Runtime MQTT persistence (may contain messages) |
Git Workflow Integration
The CI pipeline .github/workflows/ci.yml:3-9 enforces version control best practices:
Protected Branch Pattern:
- All changes to
mainrequire pull request - CI must pass before merge
- Prevents broken configuration from entering main branch
Pull Request Flow:
- Developer creates feature branch
- Pushes changes to remote
- Opens pull request to
main - CI workflow executes automatically .github/workflows/ci.yml:7-9
- If CI passes, pull request can be merged
- If CI fails, developer must fix issues
Environment Variable Security
The docker-compose.yml file docker-compose.yml:16-17 references the token without exposing it:
This pattern:
- Uses variable substitution instead of hardcoded values
- Reads from
.envfile at runtime (excluded by.gitignore) - Never logs the token value in CI output
- Follows twelve-factor app methodology
Sources: docker-compose.yml:16-17, .gitignore:1
Data Directory Management
The data/* directory .gitignore2 is excluded for several reasons:
- Size: Mosquitto may accumulate significant message data
- Privacy: MQTT messages might contain sensitive IoT data
- State: Runtime state should not be in version control
- Portability: Each deployment should have independent state
The directory is automatically created by the Mosquitto container when it starts.
Sources: .gitignore:2
Commit Hygiene for CI/CD
DO:
- Commit workflow YAML files .github/workflows/
- Commit public configuration mosquitto.conf
- Update
.env.samplewhen adding new required variables - Include descriptive commit messages for CI changes
DON’T:
- Commit
.envfiles with actual tokens - Commit
data/*runtime directories - Hardcode secrets in workflow files
- Bypass CI by pushing directly to
main
Security Checklist
Before committing changes related to CI/CD:
- Verify
.gitignoreexcludes.env - Confirm workflow files contain no hardcoded secrets
- Check that
.env.sampleis up-to-date - Ensure CI workflow would catch your changes
- Review
git statusfor untracked secret files - Use
git diff --cachedto review staged changes
Sources: .gitignore:1-2, .github/workflows/ci.yml, .github/workflows/build-docs.yml
Testing Strategy
The automated testing focuses on validating successful service startup rather than functional MQTT testing:
| Test Aspect | Implementation | Location |
|---|---|---|
| Trigger | Push or PR to main branch | .github/workflows/ci.yml:3-9 |
| Environment | ubuntu-latest runner | .github/workflows/ci.yml13 |
| Service Under Test | mosquitto only | .github/workflows/ci.yml25 |
| Health Check | Container status polling | .github/workflows/ci.yml:28-39 |
| Timeout | 100 seconds (10 × 10s) | .github/workflows/ci.yml29 |
| Cleanup | Always runs teardown | .github/workflows/ci.yml:41-42 |
Note that the cloudflared service is not tested in CI because it requires a valid CLOUDFLARE_TUNNEL_TOKEN, which is not available in the test environment. The CI validates only that the mosquitto service can successfully start in isolation.
Sources: .github/workflows/ci.yml
Development Commands
Developers use the following docker-compose commands during development:
| Command | Purpose | Effect |
|---|---|---|
docker-compose up -d | Start all services in background | Starts both mosquitto and cloudflared |
docker-compose up -d mosquitto | Start only mosquitto | Starts mosquitto without cloudflared |
docker-compose ps | Check service status | Shows running containers and their state |
docker-compose logs -f mosquitto | View mosquitto logs | Streams log output in real-time |
docker-compose down | Stop and remove services | Stops containers and removes them |
docker-compose restart mosquitto | Restart mosquitto | Stops and starts the service |
These commands interact with the service definitions in docker-compose.yml:3-17
Sources: docker-compose.yml, .github/workflows/ci.yml
Configuration Management
Environment Variables
The system uses environment variable substitution in docker-compose.yml docker-compose.yml:14-17:
The CLOUDFLARE_TUNNEL_TOKEN variable must be defined in the .env file for the cloudflared service to authenticate with Cloudflare’s network.
Volume Mounts
The mosquitto configuration is provided via volume mount docker-compose.yml:7-8:
This allows developers to modify mosquitto.conf and restart the service without rebuilding any Docker images.
Sources: docker-compose.yml
Next Steps for Developers
After understanding this overview:
- Setup Local Environment: Follow the detailed instructions in Local Development Setup to configure your workstation
- Understand CI Pipeline: Review CI/CD Pipeline for details on how automated tests validate changes
- Learn Version Control: Read Version Control Practices for guidelines on managing secrets and contributions
For advanced configuration topics such as ACLs and encryption, see Advanced Topics.
Sources: All files in this repository
Dismiss
Refresh this wiki
Enter email to refresh