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.8+
- Docker - For running PostgreSQL
- 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.
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 .
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 Transport Tuning.
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
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.
See tasks/container_based_dev_worker_plan.md for the full design.
Next Steps¶
- Contributing Guide - How to contribute to the project
- Architecture Overview - Understand the system design