Build Guide¶
This guide covers building Micromegas from source and setting up a development environment.
Prerequisites¶
- Rust - Toolchain version pinned in
rust/rust-toolchain.toml;rustupwill install it automatically on first build - Python 3.11+
- Docker - For running PostgreSQL
- Python
dockerpackage - Thelocal_test_envscripts that manage the PostgreSQL container (start_services.py,local_test_env/db/run.py) import thedockerSDK:pip install --user docker - Git
- Build tools - C/C++ compiler and linker (required for Rust compilation)
- Linux:
sudo apt-get install build-essential clang mold - macOS:
xcode-select --install - Windows: Install Visual Studio Build Tools
mold linker requirement
On Linux, the project requires the mold linker as configured in .cargo/config.toml. This provides faster linking for large projects.
Don't use apt's python3-docker on Ubuntu 24.04+ (noble)
Ubuntu noble pins python3-docker at docker-py 5.0.3, which raises
docker.errors.DockerException: ... Not supported URL scheme http+docker once
urllib3 2.x is on the path (pulled in by requests from any other tool installed
in user site-packages, which take precedence over apt's dist-packages). Install
from PyPI instead: pip install --user docker (add --break-system-packages if
pip refuses on an externally-managed system Python).
Additional CI Tools¶
For running the full CI pipeline locally, you'll need:
Rust Development¶
Clone and Build¶
git clone https://github.com/madesroches/micromegas.git
cd micromegas/rust
# Build all components
cargo build
# Build with optimizations
cargo build --release
# Build specific component
cargo build -p telemetry-ingestion-srv
Testing¶
# Run all tests
cargo test
# Run tests with output
cargo test -- --nocapture
# Run specific test
cargo test -p micromegas-tracing
Format and Lint¶
# Format code (required before commits)
cargo fmt
# Run linter
cargo clippy --workspace -- -D warnings
# Run full CI pipeline
python3 ../build/rust_ci.py
Advanced Builds¶
# Clean build
cargo clean && cargo build
# Cross-compile for Windows (from Linux)
rustup target add x86_64-pc-windows-gnu
cargo build --target x86_64-pc-windows-gnu
ARM64 Cross-Compilation¶
Production Docker images support ARM64 (aarch64) via a Docker-based cross-compilation environment. The toolchain lives in local_test_env/arm64/.
# Build the ARM64 cross-compilation Docker image
cd local_test_env/arm64
python3 build.py
# Run the image to cross-compile (mounts the repo)
python3 run.py
The Dockerfile installs g++-aarch64-linux-gnu, adds the aarch64-unknown-linux-gnu Rust target, and cross-compiles OpenSSL statically for ARM64. The build_docker_images.py script at the repo root also accepts --arm64 to build production images for ARM64.
JavaScript / TypeScript Development¶
The repository has two independent JS/TS workspaces. Both use Yarn 4 (Berry) — run corepack enable once per machine to activate the pinned version.
Analytics Web App (analytics-web-app/)¶
Vite + React 19 frontend for the analytics UI.
cd analytics-web-app
corepack enable # Once per machine
yarn install # Install dependencies
yarn dev # Vite dev server on port 3000
yarn build # Production build to dist/
yarn lint # ESLint
yarn type-check # TypeScript check (no emit)
yarn test # Vitest unit tests
Grafana Plugin (grafana/)¶
Grafana datasource plugin (React frontend + Go backend).
Additional prerequisites: Go 1.23+ and mage (go install github.com/magefile/mage@latest).
cd grafana
corepack enable # Once per machine
yarn install # Install Node dependencies
mage -v build # Build Go backend binaries
yarn build # Production bundle
yarn dev # Dev mode with hot reload
yarn test:ci # Tests
yarn lint:fix # Lint + autofix
yarn server # Start Grafana via docker compose at http://localhost:3000
Python Development¶
cd python/micromegas
# Install dependencies
poetry install
# Run tests
pytest
# Format code (required before commits)
black .
# Run full CI validation
python3 ../../build/python_ci.py
Running a Development Instance¶
Once you've built the components above, you can run a full local stack backed by your own build instead of the published Docker image (see Getting Started for the Docker quickstart).
Environment Variables¶
# Database credentials (used by setup scripts)
export MICROMEGAS_DB_USERNAME=your_username
export MICROMEGAS_DB_PASSWD=your_password
# Service endpoints
export MICROMEGAS_TELEMETRY_URL=http://localhost:9000
export MICROMEGAS_SQL_CONNECTION_STRING=postgres://your_username:your_password@localhost:5432
# Object storage (replace with your local path)
export MICROMEGAS_OBJECT_STORE_URI=file:///path/to/local/storage
Object Storage Path
Choose a local directory for object storage, e.g., /tmp/micromegas-storage or C:\temp\micromegas-storage on Windows.
Advanced: transport tuning
The Rust telemetry sink exposes environment variables for queue size limits, concurrency, and timeouts if the ingestion service falls behind or becomes unreachable. See Telemetry Sink Configuration.
Option A: Monolith (recommended)¶
The simplest way to start everything is the monolith script, which builds and launches a single micromegas-monolith process running all roles (ingestion, analytics, web, maintenance):
This will automatically:
- Build the monolith binary and the analytics web app (including DataFusion WASM)
- Start PostgreSQL if not already running
- Launch
micromegas-monolith --roles allon port 9000 (HTTP/ingestion), port 50051 (FlightSQL), and port 3000 (web app) - Write all PIDs to
/tmp/micromegas_pids.txt
Option B: Split Services¶
To run the four services separately (closer to a production topology):
Option C: Manual Startup¶
If you prefer full control, start each service in a separate terminal:
Terminal 1: PostgreSQL Database
Terminal 2: Ingestion Server
Terminal 3: FlightSQL Server
Terminal 4: Maintenance Service
Service Roles
- PostgreSQL: Stores metadata and service configuration
- Ingestion Server: Receives telemetry data from applications (port 9000)
- FlightSQL Server: Provides SQL query interface for analytics (port 50051)
- Maintenance Service: Handles background processing and global view materialization
Documentation¶
# Install dependencies
pip install -r mkdocs/docs-requirements.txt
# Start development server
cd mkdocs
mkdocs serve
# Build static site
mkdocs build
CI additionally runs python3 build/check_docs_site.py public_docs from the repo root,
after publish-docs.yml stages the docs build, the welcome page, and the presentations into
public_docs/. It validates that every sitemap URL, canonical tag, and feed autodiscovery
link in that staged tree resolves to a file that actually exists — it is not a command you
run from mkdocs/ against mkdocs build's own output alone.
Self-Hosted CI Runner¶
Developer workstations can contribute to CI builds using a Docker-based self-hosted GitHub Actions runner. Builds from the repo owner route to the dev worker when it's online, falling back to GitHub-hosted runners when it's not.
Prerequisites¶
- Docker
- A fine-grained GitHub PAT with
Administration: Read and writescoped tomadesroches/micromegas
Setup¶
Store the PAT locally (choose one):
# Option 1: environment variable
export MICROMEGAS_RUNNER_PAT=ghp_xxx
# Option 2: file (recommended for persistent use)
mkdir -p ~/.config/micromegas
echo "ghp_xxx" > ~/.config/micromegas/runner-pat
chmod 600 ~/.config/micromegas/runner-pat
The same PAT must be stored as the repository secret RUNNER_PAT:
Usage¶
# Start the worker (runs until Ctrl+C)
python3 build/dev_worker.py
# With resource limits
python3 build/dev_worker.py --cpus 8 --memory 16g
# Build the container image without starting the worker
python3 build/dev_worker.py --build-image
# Remove offline dev-worker runners from GitHub and exit
python3 build/dev_worker.py --cleanup
How It Works¶
Each workflow has a check-runner job that runs on ubuntu-latest and decides where the real jobs run:
- If the build author is the repo owner and a dev worker is online, jobs route to
dev-worker - Otherwise, jobs run on
ubuntu-latest(existing behavior)
The runner container is ephemeral: each container registers with GitHub, picks up one job, executes it, and exits. The worker loop then starts a fresh container for the next job. Each container gets a unique name so successive runs cannot collide while Docker drains the previous --rm cleanup.
The build caches live in a named Docker volume (micromegas-runner-cache) mounted at /cache, so they persist across the ephemeral containers. The volume holds:
- Cargo registry and target directories (
CARGO_HOME,CARGO_TARGET_DIR) - Yarn package downloads (
YARN_CACHE_FOLDER) - Go module and build cache (
GOMODCACHE,GOCACHE) - Playwright browser downloads (
PLAYWRIGHT_BROWSERS_PATH)
This assumes a single worker per workstation — two concurrent workers sharing the volume would corrupt cargo's locks. To wipe the cache, stop the worker and run docker volume rm micromegas-runner-cache.
Next Steps¶
- Contributing Guide - How to contribute to the project
- Architecture Overview - Understand the system design