Skip to content

Configuration reference

Yagra is configured entirely through environment variables — there is no configuration file. The binaries read their environment once at process start, so changing a value means restarting the affected container. With the bundled compose files you set variables in a .env file next to the compose file; see the installation guide for the initial setup.

There are two kinds of variables on this page:

  • Variables read by the binaries (yagra-core, yagra-poller, or both) — these work in any deployment, whether or not you use the bundled compose files.
  • Compose-only variables — consumed by Docker Compose or the bundled NATS server configuration when interpolating the compose files. The binaries never see them. They are listed in their own section at the end.

Secrets are files, not values. The three secret-bearing variables — YAGRA_KEK_FILE, YAGRA_SESSION_KEY_FILE, and YAGRA_NATS_CALLOUT_SEED_FILE — carry the path to a mounted file. The secret itself never appears in an environment value, so it is not exposed through docker inspect or the process environment.

Boolean variables (YAGRA_PUBLIC_DASHBOARD, YAGRA_ENABLE_HA, YAGRA_ENABLE_MCP) are true for 1, true, yes, or on (case-insensitive) and false for anything else, including unset. The one deliberate exception is YAGRA_STORE_FORWARD, which is on by default — see its row under store-and-forward.

In the tables below, a dash (—) in the Default column means the variable has no default and the Purpose cell describes what happens without it.

Variables read by the yagra-core binary — orchestration, scheduling, and the northbound REST API.

Each kind of data lives in the store built for it (see the architecture overview). Core needs PostgreSQL, the bus, and VictoriaMetrics to run in live mode; the other stores are optional.

Variable Default Purpose
YAGRA_DATABASE_URL — (required) PostgreSQL connection URL for the metadata store. The connection is retried 30 times at 2 s intervals at startup.
YAGRA_TSDB_URL — (required) VictoriaMetrics base URL — the time-series metrics store.
YAGRA_REDIS_URL unset Redis URL for the volatile poller liveness/assignment mirror. Unset, blank, or unreachable ⇒ core degrades to a no-op mirror with a one-time log — never fatal. The mirror is rebuildable, so losing Redis is safe.
YAGRA_LOGS_URL unset VictoriaLogs base URL — the searchable passive-event store. Unset ⇒ passive events stay entirely in PostgreSQL.
YAGRA_CLICKHOUSE_URL unset ClickHouse HTTP URL — the traffic-flow store. Unset ⇒ the flow receiver is disabled and the flow API returns 503.
YAGRA_PG_MAX_CONNECTIONS 20 Connection-pool ceiling for the whole core process. With high availability enabled, the leader’s advisory-lock connection is one extra on top of this pool — size PostgreSQL’s max_connections accordingly.
Variable Default Purpose
YAGRA_API_ADDR 0.0.0.0:8080 Bind address for the REST API. Also read by the container health check to derive its probe port.
YAGRA_PUBLIC_DASHBOARD false Serve read-only endpoints without authentication (public dashboard). Writes stay authenticated.
YAGRA_ADMIN_PASSWORD unset First-boot password for the admin account, consulted only when the account is first seeded. Unset or blank ⇒ core generates a random one-time bootstrap password and logs it once — there is no well-known default password.
YAGRA_SESSION_KEY_FILE unset Path to a mounted HMAC session-signing key (64 hex characters or 32 raw bytes). Enables stateless signed session tokens that survive core restarts and work across an HA pair. Unset ⇒ opaque per-process tokens.
YAGRA_PAT_OIDC_IDLE_DAYS 30 How long an API token owned by an SSO-provisioned account survives its owner not signing in. Yagra is never told when an identity provider disables an account, so the owner going quiet is the only signal available; local- and service-account-owned tokens are unaffected. Clamped to 1–365; it cannot be switched off.
YAGRA_KEK_FILE unset Path to the mounted key-encryption key (KEK) that envelope-encrypts monitoring credentials at rest.

The WebUI is served over HTTPS by default. Core holds the certificate of record in PostgreSQL, envelope-encrypted under the same KEK as every other secret, and materializes it into a volume the web container reads. See Security for the full picture.

Variable Default Purpose
YAGRA_TLS_DIR unset Directory core materializes the certificate bundle into, for the web container’s nginx to read. Unset ⇒ nothing is written — the shape for a deployment that terminates TLS somewhere else. The bundled compose files set it to /var/lib/yagra/tls.
YAGRA_TLS_SELF_SIGNED_SANS unset Comma-separated names the bootstrap self-signed certificate covers. Unset ⇒ loopback plus the container’s hostname. Nothing inside the container can know the address you will actually type, so either set this or regenerate from Settings ▸ TLS with the right names.
YAGRA_API_BIND unset (⇒ 0.0.0.0) Host interface core’s plaintext API port is published on. Core reads it too, but only so Settings ▸ TLS can report whether that port is still reachable from the LAN — it does not change what core binds inside the container. Set it to 127.0.0.1 after moving Prometheus scrapes, webhook senders and API scripts to the TLS edge.

These four are read by the web container’s entrypoint, not by either Rust binary:

Variable Default Purpose
YAGRA_WEB_TLS on off / false / 0 serves plain HTTP on the container’s 8080 instead — the supported shape when a reverse proxy or load balancer already terminates HTTPS in front of it.
YAGRA_WEB_TLS_CERT /etc/nginx/certs/server.pem Path to the combined chain + key bundle inside the web container. One file holds both, so a certificate can never be read alongside a key that does not match it.
YAGRA_WEB_TLS_WAIT_SECS 90 How long the entrypoint waits for that file before giving up. Timing out is a hard failure: TLS was requested, so the container refuses to start rather than silently downgrading to plaintext.
YAGRA_WEB_TLS_RELOAD_SECS 15 How often the entrypoint hashes the bundle to notice an imported or regenerated certificate. A change is applied with nginx -s reload, and only after nginx -t passes — a bad certificate leaves the previous configuration serving rather than taking the UI down.
Variable Default Purpose
YAGRA_POLL_INTERVAL_SECS 30 Initial default polling interval in seconds, clamped to 10–3600. First boot only: the value seeds the stored setting once; from then on the value in the WebUI settings is authoritative and this variable is ignored.
YAGRA_SNMP_COMMUNITY unset Fallback SNMP v2c community for nodes without a bound credential. Unset or empty ⇒ no fallback — such nodes need a credential assigned.
YAGRA_MERAKI_POOL default Poller pool that Meraki cloud-poll jobs are routed to.

The environment-configured Webhook and email channels are always-on defaults that fire alongside any notification channels configured in the WebUI.

Variable Default Purpose
YAGRA_WEBHOOK_URL unset Default alert notification Webhook — fires for every alert. Unset or empty ⇒ no environment Webhook channel.
YAGRA_SMTP_HOST unset SMTP relay host for the default email channel. The channel is enabled only when YAGRA_SMTP_HOST, YAGRA_SMTP_FROM, and YAGRA_SMTP_TO are all set.
YAGRA_SMTP_PORT 465 SMTP port. The default is implicit TLS (SMTPS).
YAGRA_SMTP_FROM unset Email From address. Must parse as a valid mailbox or the channel is dropped.
YAGRA_SMTP_TO unset Email To address. Must parse as a valid mailbox.
YAGRA_SMTP_USER unset SMTP auth username. Credentials are applied only when both YAGRA_SMTP_USER and YAGRA_SMTP_PASS are set.
YAGRA_SMTP_PASS unset SMTP auth password.
YAGRA_POOL_COVERAGE_ALERT_AFTER_SECS 300 How long a poller pool must hold nodes with no live poller before Yagra raises a critical alert about its own monitoring coverage. A poller announces its own departure, so an ordinary rolling restart raises the condition instantly — this debounce is what keeps that from paging anyone. 0 disables the alert; the yagra_pools_without_live_poller and yagra_pool_nodes_without_live_poller gauges are exported either way.

See the high-availability guide for the full active/passive setup.

Variable Default Purpose
YAGRA_ENABLE_HA false Opt-in active/passive core pair with leader election over a PostgreSQL advisory lock. Off ⇒ single active core, identical to the non-HA behavior.
YAGRA_CORE_ID unset Human-readable id of this core instance, shown in HA logs and diagnostics. Unset ⇒ a generic label.

The optional MCP tool surface for AI clients — see the MCP server page.

Variable Default Purpose
YAGRA_ENABLE_MCP false Mount the MCP tool surface at /mcp. Off ⇒ requests to /mcp return 404. Authentication on /mcp is always required, even when the public dashboard is enabled.
YAGRA_MCP_ALLOWED_HOSTS unset Optional comma-separated host[:port] allowlist that pins the Host header on /mcp (DNS-rebinding hardening). Unset or empty ⇒ any Host is accepted; the mandatory Bearer authentication remains the gate.

Caps on Troubleshoot analysis jobs and AI root-cause-analysis (RCA) generations. RCA generations call an external LLM, so the RCA caps also bound spend.

Variable Default Purpose
YAGRA_ANALYSIS_MAX_CONCURRENT 4 Cap on concurrently running Troubleshoot analysis jobs.
YAGRA_ANALYSIS_RATE_PER_MIN 30 Cap on new analysis jobs admitted per minute (sliding 60 s window).
YAGRA_RCA_MAX_CONCURRENT 2 Cap on simultaneous AI RCA generations.
YAGRA_RCA_RATE_PER_MIN 10 Cap on new RCA generations per minute (sliding 60 s window).
YAGRA_RCA_CACHE_SECS 900 RCA report cache lifetime in seconds. Forcing a regeneration bypasses the cache but not the rate caps.
YAGRA_RCA_MAX_TURNS 6 How many tool-calling turns an LLM root-cause analysis may take before it has to answer. Since v0.1.23 the analysis can call the read-only MCP tools to look things up for itself; setting this to 1 restores the previous single-shot behaviour exactly — no tools are offered and the request sent to the provider is byte-identical to before.
YAGRA_RCA_TASK_BUDGET_SECS 240 Wall-clock ceiling in seconds for one root-cause analysis, including its tool calls. Hitting the bound returns the model’s last answer rather than failing the request.

The flow store connection itself is YAGRA_CLICKHOUSE_URL (see Backing stores above); these variables tune retention and IP→ASN enrichment. See the traffic-flow feature page.

Variable Default Purpose
YAGRA_FLOW_RETENTION_DAYS 30 Flow-record retention in days (applied as a ClickHouse TTL), clamped to 1–3650.
YAGRA_IPASN_DB unset Path to an offline iptoasn.com TSV dataset for flow IP→ASN enrichment. Unset ⇒ enrichment is off and only exporter-provided AS numbers are used. A missing or unreadable file logs a warning and disables enrichment — never fatal.
YAGRA_IPASN_RELOAD_SECS 0 Period in seconds for hot-reloading the IP→ASN dataset without a restart. 0 ⇒ load once at startup, no reload task.

When the bus is exposed to remote pollers, core can act as the NATS Auth Callout service and mint per-poller bus credentials scoped to exactly the subjects that poller needs. All three variables work together; without the seed file and the poller password, the responder is simply not started and NATS falls back to its static accounts.

Variable Default Purpose
YAGRA_NATS_CALLOUT_SEED_FILE unset Path to a mounted NATS account nkey seed file used to sign callout responses. Unset ⇒ the Auth Callout responder is not started.
YAGRA_NATS_CALLOUT_ACCOUNT $G NATS account that minted poller users are placed into; must match the account named in the server’s auth_callout block.
YAGRA_NATS_POLLER_PASSWORD unset Shared poller bootstrap secret the callout validates connecting pollers against. Unset ⇒ the responder cannot authenticate anyone and is not started. Also interpolated into the bundled NATS server configuration (see compose-only variables).

Variables read by the yagra-poller binary — the stateless polling worker that also hosts the passive-event and traffic-flow edge listeners.

Variable Default Purpose
YAGRA_POLLER_ID hostname Stable poller identity used in heartbeats, working-set assignment, and the Settings ▸ Pollers page. Unset or empty ⇒ the machine hostname; if that is unresolvable, a random poller- id. Sanitized to A–Z a–z 0–9 _ -.
YAGRA_POLLER_POOL default Poller pool this poller serves for node assignment (see distributed polling). When unset, passive events and flows received by this poller are tagged with no pool rather than default.
YAGRA_POLLER_QUEUE pollers NATS queue-group name for the legacy per-job fan-out path.
YAGRA_BUS_CA_FILE unset CA / server-certificate file used to pin the NATS server certificate for tls:// bus URLs (remote pollers). Unset or empty ⇒ no pinning — the plaintext single-node path.
Variable Default Purpose
YAGRA_MAX_CONCURRENT_POLLS 64 Bound on total concurrent probes. Each device is additionally limited to one in-flight probe at a time.

Syslog and SNMP-trap reception (see passive events). Each listener stays disabled until its bind address is set. The two YAGRA_LISTENER_* variables tune every edge listener, including the traffic-flow listeners in the next section.

Variable Default Purpose
YAGRA_SYSLOG_BIND unset UDP bind address for the syslog listener (e.g. 0.0.0.0:1514). Unset or empty ⇒ listener disabled. A failed bind is logged and the listener skipped — not fatal.
YAGRA_TRAP_BIND unset UDP bind address for the SNMP-trap listener (e.g. 0.0.0.0:1162) — v1/v2c traps and informs. Unset or empty ⇒ listener disabled.
YAGRA_TRAP_COMMUNITY unset Drop traps whose community string does not match. Unset or empty ⇒ no community filter — all traps accepted. The value is never logged.
YAGRA_EVENT_RATE_PER_SOURCE 200 Per-source-IP events-per-second cap for syslog + trap intake (one shared token bucket per source; minimum effective rate 0.1).
YAGRA_EVENT_RATE_GLOBAL 5000 Global events-per-second cap across all sources for syslog + trap intake.
YAGRA_LISTENER_WORKERS auto (1–4) Parallel reader sockets per edge listener. Defaults to the host’s available parallelism clamped to 1–4; platforms without SO_REUSEPORT always use a single socket.
YAGRA_LISTENER_RCVBUF_BYTES 4194304 Socket receive-buffer (SO_RCVBUF) size per listener socket — 4 MiB by default.

NetFlow, IPFIX, and sFlow reception. Flow datagrams have their own rate budget, separate from syslog and traps.

Variable Default Purpose
YAGRA_FLOW_BIND unset UDP bind address for NetFlow v5/v9 and IPFIX (e.g. 0.0.0.0:2055). Unset or empty ⇒ listener disabled.
YAGRA_SFLOW_BIND unset UDP bind address for sFlow v5 (e.g. 0.0.0.0:6343). Shares the rate limiter, aggregator, and flusher with the NetFlow listener.
YAGRA_FLOW_RATE_PER_SOURCE 1000 Per-source cap in datagrams per second (not flow records).
YAGRA_FLOW_RATE_GLOBAL 20000 Global flow-datagram cap across all exporters.
YAGRA_FLOW_TOP_N 500 Top flows (by bytes) kept per bucket per exporter — the primary cardinality control for the flow store.
YAGRA_FLOW_BUCKET_SECS 60 Flow aggregation bucket width in seconds.

A remote poller buffers results through a network partition — in memory, spilling to disk — and replays them when the link returns (see distributed polling).

Variable Default Purpose
YAGRA_STORE_FORWARD on Master switch for the result buffer. Set off, false, 0, or no (case-insensitive) to disable; any other value — including unset — means on. Off ⇒ pure pass-through: results publish live and are dropped on failure.
YAGRA_STORE_FORWARD_DIR /var/lib/yagra/buffer On-disk spill directory; the bundled compose files mount a named volume here. If the directory cannot be created or scanned, the poller degrades to memory-only buffering — it never crashes.
YAGRA_STORE_FORWARD_MEM_MAX 20000 In-memory ring size (in results) before the oldest results spill to disk.
YAGRA_STORE_FORWARD_DISK_MAX_MB 512 Maximum total on-disk spill in MB, enforced by dropping whole oldest segments.
YAGRA_STORE_FORWARD_MAX_AGE_SECS 86400 Buffered results older than this (default 24 h) are dropped at replay time.
YAGRA_STORE_FORWARD_DISK_FREE_FLOOR_MB 1024 Stop spilling when the filesystem’s free space drops below this many MB — a host-disk safety floor.
YAGRA_STORE_FORWARD_SEGMENT_MB 16 Spill-segment roll size in MB — the granularity of the disk cap. 0 or an unparseable value falls back to the built-in 16 MiB.
Variable Default Purpose
YAGRA_BUS_URL NATS bus URL — nats://host:4222, or tls://user:pass@host:4222 for remote sites. Core requires it for live mode (see skeleton mode above); a poller without it logs a warning and idles. Both binaries retry the connection 30 times at 2 s intervals.
Variable Default Purpose
YAGRA_DISK_WATCH_PATHS /=root Comma-separated list of path or path=alias entries — the filesystems host self-metrics report capacity for. The alias becomes the metric’s mount label (derived from the last path segment when omitted). Unreadable paths are silently omitted from samples.
Variable Default Purpose
YAGRA_OTEL_ENDPOINT unset OTLP/HTTP endpoint for OpenTelemetry span export (e.g. http://jaeger:4318). Unset or empty ⇒ spans are not exported — structured logs only. A bad endpoint prints a warning and falls back to logs-only; it never aborts startup.
OTEL_EXPORTER_OTLP_ENDPOINT unset Standard OpenTelemetry fallback endpoint, consulted only when YAGRA_OTEL_ENDPOINT is unset.
OTEL_TRACES_SAMPLER parentbased_always_on Trace sampler. Recognized values: always_on, always_off, traceidratio, parentbased_always_off, parentbased_traceidratio; anything else falls back to the default (sample everything). At scale, prefer parentbased_traceidratio.
OTEL_TRACES_SAMPLER_ARG 1.0 Sampling ratio for the ratio-based samplers, clamped to 0.0–1.0.
YAGRA_LOG_DIR unset Directory for hourly-rotated JSON-lines log files, written in addition to stdout — never instead of it. It exists for deployments where nobody can reach docker logs, which is exactly where a panic or an OOM would otherwise leave nothing retrievable; the support bundle reads these files back over HTTP, so a bundle taken after a recovery still carries the run that died. Unset ⇒ stdout only. Writes are non-blocking and drop rather than stall the poll loop, and an unwritable directory degrades to stdout-only with a warning instead of failing startup.
YAGRA_LOG_RETAIN_HOURS 48 How many hourly log files to keep in YAGRA_LOG_DIR, pruned automatically so an unattended deployment cannot fill its volume with its own logs.
RUST_LOG info Structured-log filter in standard tracing EnvFilter syntax — a plain level (debug) or per-module directives.

These variables are consumed by Docker Compose (or the bundled NATS server configuration) when interpolating the compose files — the binaries never read them. Set them in the .env file next to the compose file you run. The Used by column abbreviates: deploy = docker-compose.deploy.yml (pull-only server composition), poller = docker-compose.poller.yml (standalone remote-site poller), single-node = docker-compose.yml, and nats = docker/nats/nats-server.conf.

Variable Default Used by Purpose
YAGRA_IMAGE_TAG latest deploy, poller Tag of the three published ghcr.io/horryworks/yagra-* images to pull. latest is the latest stable release; pin a v<version> tag for production.
POSTGRES_PASSWORD yagra deploy PostgreSQL password — interpolated into both the postgres container and core’s YAGRA_DATABASE_URL. Change it in production.
YAGRA_API_PORT 8080 deploy Host port mapped to core’s API port.
YAGRA_WEB_PORT 443 deploy Host port mapped to the WebUI container — HTTPS. The single-node build composition defaults it to 8443 instead, so an evaluation stack does not need a privileged port.
YAGRA_SYSLOG_PORT 514 deploy Host UDP port mapped to the poller’s syslog listener (container port 1514).
YAGRA_TRAP_PORT 162 deploy Host UDP port mapped to the SNMP-trap listener (container port 1162).
YAGRA_FLOW_PORT 2055 deploy Host UDP port mapped to the NetFlow/IPFIX listener.
YAGRA_SFLOW_PORT 6343 deploy Host UDP port mapped to the sFlow listener.
YAGRA_NATS_PORT 4222 deploy Host port to publish the NATS bus on (commented out by default). Only expose the bus with TLS + authentication enabled.
YAGRA_CERT_DIR ./certs deploy, poller Host directory bind-mounted for the NATS server certificate (server side) and the poller’s CA certificate (remote side, pairs with YAGRA_BUS_CA_FILE).
YAGRA_NATS_CORE_PASSWORD — (required) deploy, nats Password for the core user in the NATS static-auth configuration. The NATS server exits at startup if it is referenced but unset — fail-closed, never a silent default.
YAGRA_NATS_CALLOUT_ISSUER — (required) deploy, nats Account public key (A…) the NATS server verifies core’s Auth Callout JWTs against. Required when the callout block is enabled; fail-closed like the core password.
YAGRA_CALLOUT_SEED_DIR ./callout deploy Host directory holding account.seed, mounted read-only into core. Pairs with YAGRA_NATS_CALLOUT_SEED_FILE.
YAGRA_SESSION_KEY_DIR ./session deploy Host directory holding session.key, mounted read-only into the core container(s). Pairs with YAGRA_SESSION_KEY_FILE.
YAGRA_IPASN_URL https://iptoasn.com/data/ip2asn-combined.tsv.gz deploy, single-node Dataset URL the ipasn-updater sidecar fetches — the only container that needs egress for AS enrichment.
YAGRA_IPASN_REFRESH_SECS 604800 deploy, single-node Fetch cadence of the ipasn-updater sidecar — 7 days by default.
Variable Default Purpose
VITE_API_BASE empty The API origin — scheme + host + port, never a path — that the WebUI’s API and SSE clients call. Baked in at build time by Vite; it cannot be changed on a built image. Empty ⇒ same-origin: the production image serves the WebUI behind its bundled nginx, which proxies /api to core. Set it only when building the WebUI yourself against a core on another host.