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.
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.
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.1after 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.
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.
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).
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.
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.
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.
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.
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.
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 tracingEnvFilter 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.
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.