Docker¶
Use the Docker image when you want Sonda without a local Rust toolchain. Common cases are CI runners, a colleague's laptop, or running alongside the bundled observability stacks (Prometheus, VictoriaMetrics, Grafana) shown later on this page. The image is a single artifact. It carries both the sonda CLI and the sonda-server HTTP API. The same docker run works for a one-shot scenario or a long-running server.
Run a scenario in three commands¶
Pre-built multi-arch images are published to GitHub Container Registry on each release. Pull the image, point it at a scenario file on your machine, and view the output:
# 1. Pull the published image (Docker picks the right architecture for your host)
docker pull ghcr.io/davidban77/sonda:latest
# 2. Generate a starter scenario file in the current directory
docker run --rm -v "$PWD":/work -w /work \
ghcr.io/davidban77/sonda:latest \
new --template -o hello.yaml
# 3. Run it — synthetic metrics stream to your terminal
docker run --rm -v "$PWD":/work -w /work \
ghcr.io/davidban77/sonda:latest \
run hello.yaml --duration 5s
That last command prints five Prometheus-format metric lines and a completion banner. The output matches a locally installed sonda. The -v "$PWD":/work -w /work flags mount your current directory into the container so sonda can read the YAML file and write the starter file back out.
From here you can run your own scenarios, start the HTTP server, or use one of the bundled stacks. See Running with Docker below for the server and Docker Compose stacks for the bundled options. Most readers use the published image and never build their own. The build instructions are at the end of the page for when you do.
Running with Docker¶
The default entrypoint is sonda-server. It starts the HTTP API on port 8080. See Server API for the full endpoint reference.
# Start the server (default behaviour)
docker run -p 8080:8080 ghcr.io/davidban77/sonda:latest
# Run the CLI against a mounted catalog by @name
docker run --rm \
-v "$PWD/my-catalog":/catalog \
ghcr.io/davidban77/sonda:latest \
run @cpu-spike --catalog /catalog
# List what's in the mounted catalog
docker run --rm \
-v "$PWD/my-catalog":/catalog \
ghcr.io/davidban77/sonda:latest \
list --catalog /catalog
# Or run a single file directly
docker run --rm \
-v "$PWD/scenarios":/work \
ghcr.io/davidban77/sonda:latest \
run /work/cpu-spike.yaml
argv[1] must be the subcommand
The default entrypoint is sonda-server. It inspects argv[1] and runs the sibling sonda CLI when it matches one of the four subcommands (run, list, show, new). That means global flags like --catalog belong after the subcommand when using the default entrypoint. Use sonda run @x --catalog /catalog, not sonda --catalog /catalog run @x. The host CLI accepts both orderings. The Docker constraint comes from the shim that runs the sibling binary, not clap.
For invocations that don't start with a subcommand (--help, --version, or the global-flag-first style), override the entrypoint:
The image has no built-in catalog. Mount a directory of your own scenario and pack YAML files (typically kind: runnable and kind: composable files) at any path inside the container. Pass --catalog <path> to point sonda at it. See Catalogs for the directory layout.
Pre-1.9 env vars are gone
Earlier releases let the image discover scenarios from SONDA_PACK_PATH=/packs and SONDA_SCENARIO_PATH=/scenarios environment variables. The image also included companion /packs and /scenarios directories. Both were removed in 1.9. Discovery is explicit through --catalog <dir>. There is no environment variable fallback and no implicit search path. Old recipes built around docker run … run @scenario fail with "catalog dir does not exist or is not a directory" or a @name resolution error. Add --catalog /catalog and mount your catalog volume there.
Authentication¶
You can protect the server's /scenarios/* endpoints with API key authentication.
Pass the key through the SONDA_API_KEY environment variable. It works the same
way as the --api-key CLI flag.
Once enabled, all /scenarios/* requests require a Bearer token. The /health
endpoint stays public so health probes keep working.
# Authenticated request
curl -H "Authorization: Bearer my-secret-key" \
http://localhost:8080/scenarios
# Health check (no auth needed)
curl http://localhost:8080/health
Don't embed secrets in plain text
The inline examples above are fine for local development. For production, use
Docker secrets or a .env file instead of hardcoding the key in your compose file.
See Server API -- Authentication for the full reference, including error responses, protected vs. public endpoints, and Prometheus scrape configuration.
Docker Compose Stack¶
A docker-compose.yml is provided with sonda-server, Prometheus, Alertmanager, and Grafana
for smoke-testing scenario submission and exploring the control plane.
| Service | Port | Description |
|---|---|---|
sonda-server |
8080 | Sonda HTTP API |
prometheus |
9090 | Prometheus (scrape or remote write) |
alertmanager |
9093 | Alertmanager for alert routing |
grafana |
3000 | Grafana dashboards (password: admin) |
Scenarios sent here write to container stdout
The two scenario files referenced below (docker-metrics.yaml,
docker-alerts.yaml) use sink: stdout. When you send them to sonda-server,
the generated events arrive on the server container's stdout. View them with
docker logs sonda-server. Nothing reaches Prometheus or Grafana in this stack.
This stack is useful for verifying sonda-server accepts and runs your scenario
body. To see data flowing into Prometheus and Grafana, use the
VictoriaMetrics Stack below. It includes scenarios
that push to an HTTP backend reachable from inside the container.
The Endpoints & networking page explains why a sink URL resolves
differently depending on where sonda runs.
Start, use, and tear down:
# Start the stack
docker compose up -d
# Verify the server
curl http://localhost:8080/health
# Post a metrics scenario (events go to sonda-server container stdout)
curl -X POST -H "Content-Type: text/yaml" \
--data-binary @examples/docker-metrics.yaml \
http://localhost:8080/scenarios
# Post an alert-testing scenario
curl -X POST -H "Content-Type: text/yaml" \
--data-binary @examples/docker-alerts.yaml \
http://localhost:8080/scenarios
# Inspect the generated events
docker logs -f sonda-server
# List running scenarios
curl http://localhost:8080/scenarios
# Tear down
docker compose down
Grafana is still provisioned at http://localhost:3000 and Prometheus at http://localhost:9090. They will not show sonda data from the stdout scenarios above. Use the VictoriaMetrics Stack for that.
Swapping stdout for http_push in this stack
Rewrite either scenario to push to Prometheus's remote-write receiver
(http://prometheus:9090/api/v1/write). See
Endpoints & networking. Use
${VAR:-default} so one file works from both host CLI and inside the container,
or sed the URL before posting.
Two scenario files are provided for this stack:
docker-metrics.yaml-- CPU sine wave (30--70%) with recurring gaps for testing gap-fill behavior.docker-alerts.yaml-- Sine wave (0--100) crossing warning/critical thresholds with burst windows.
See Example Scenarios for the full catalog.
VictoriaMetrics Stack¶
A dedicated compose file adds VictoriaMetrics, vmagent, and Grafana with a pre-provisioned datasource and a pre-loaded Sonda Overview dashboard.
| Service | Port | Description |
|---|---|---|
sonda-server |
8080 | Sonda HTTP API |
victoriametrics |
8428 | VictoriaMetrics single-node TSDB |
vmagent |
8429 | Metrics relay agent |
grafana |
3000 | Grafana with VictoriaMetrics datasource |
# Start the stack
docker compose -f examples/docker-compose-victoriametrics.yml up -d
# Push metrics via sonda-server
curl -X POST -H "Content-Type: text/yaml" \
--data-binary @examples/victoriametrics-metrics.yaml \
http://localhost:8080/scenarios
# Verify data arrived
curl "http://localhost:8428/api/v1/series?match[]={__name__=~'sonda.*'}"
# Tear down
docker compose -f examples/docker-compose-victoriametrics.yml down -v
The scenario URL uses ${VICTORIAMETRICS_URL:-http://localhost:8428/...}. The compose
file sets VICTORIAMETRICS_URL on the sonda-server container, so the scenario
resolves the in-network service name when sent over HTTP. The default applies when
you run the scenario from your host CLI. See
Endpoints & networking for the pattern.
You can also push from the host CLI with a pipe to VictoriaMetrics.
See Sinks for all available sink types (http_push, remote_write, loki, etc.).
version: 2
kind: runnable
defaults:
rate: 10
duration: 30s
encoder:
type: prometheus_text
sink:
type: stdout
labels:
job: sonda
instance: local
scenarios:
- id: sonda_demo
signal_type: metrics
name: sonda_demo
generator:
type: sine
amplitude: 40.0
period_secs: 30
offset: 60.0
sonda run sonda-demo.yaml \
| curl -s --data-binary @- \
-H "Content-Type: text/plain" \
"http://localhost:8428/api/v1/import/prometheus"
Explore metrics in the VictoriaMetrics UI at http://localhost:8428/vmui, or open Grafana and go to Dashboards > Sonda > Sonda Overview.
Tip
The stack includes vmagent for remote write relay. You can push protobuf metrics
through vmagent with examples/remote-write-vm.yaml.
See Encoders for details.
Alerting Profile¶
Add vmalert, Alertmanager, and a webhook receiver to test the full alerting path:
| Service | Port | Description |
|---|---|---|
vmalert |
8880 | Rule evaluation engine |
alertmanager |
9093 | Alert routing and notification |
webhook-receiver |
8090 | HTTP echo server (shows alert payloads) |
Push a threshold-crossing metric and observe alerts arrive at the webhook:
See the Alerting Pipeline guide for the full walkthrough.
Building the Image¶
Most readers use the published ghcr.io/davidban77/sonda image and never need this section. Build your own only when you want a local image from a working tree. One example is testing an unreleased change.
The multi-stage Dockerfile compiles static musl binaries and copies them into a scratch base. The final image is typically under 20 MB.
For multi-arch builds (linux/amd64 and linux/arm64) using Docker Buildx:
The pre-built multi-arch images on GitHub Container Registry come from this same Dockerfile on each release. Docker pulls the correct architecture for your host automatically: