All environment variables are declared and validated in a single place — packages/env
(server.ts for the server, web.ts for the browser bundle) — using @t3-oss/env-core
Zod at import time. No other package parses process.env directly.
Much of what used to be env-only is now DB-backed runtime configuration editable from
the Settings screen (no restart, no redeploy). For those variables the
env value is used only as a seed the first time the server boots with no saved setting;
once you save that setting from the UI, the env var is ignored.
Variables below are marked:
env-only — always read from the environment.
seed only — seeds a DB setting on first boot, then superseded by
Settings.
Active profile id. Optional; when unset the server boots onboarding-only until a profile is installed and activated. Seeds the activeProfile setting; changing the active profile takes effect on restart.
INVERTER_HOST
string
192.168.1.100
seed only
Modbus TCP host.
INVERTER_PORT
number
502
seed only
Modbus TCP port.
INVERTER_UNIT_ID
number
1
seed only
Modbus unit / slave id.
INVERTER_SIMULATE
boolean
true
env-only
Generate synthetic telemetry instead of reading real hardware. Deliberately deploy-level, not in DB config.
POLL_INTERVAL_MS
number
1000
seed only
Poll cadence in ms (floored at 1000).
HISTORY_FLUSH_INTERVAL_MS
number
5000
env-only
How often buffered history rows are flushed to TimescaleDB in one transaction. Batching cuts SSD write wear (TBW) at 1 Hz; live data is unaffected (served from memory). A crash can lose at most this window of history. Set ≤ poll interval to disable batching.
Two connection fields are DB-only (no env seed): transport (tcp / rtu-over-tcp) and
timeout (default 2000 ms). Set them from Settings → Inverter.
Static keys accepted by the public /api/v1 surface, in addition to admin-managed keys (Settings → API Keys). Empty = open in dev, fails closed in production.
Where the browser reaches the API. Read at runtime via $env/dynamic/public — nothing is baked into the image. Unset = resolved from the document URL, which keeps reverse-proxy path prefixes (HA ingress) intact; set it only for split-origin deployments like the plain Compose stack.