pub struct Config {Show 87 fields
pub database_url: String,
pub data_dir: PathBuf,
pub recordings_dir: PathBuf,
pub clips_dir: PathBuf,
pub snapshots_dir: PathBuf,
pub frames_dir: PathBuf,
pub playback_dir: PathBuf,
pub ffmpeg_bin: String,
pub ffprobe_bin: String,
pub mediamtx_api_url: String,
pub mediamtx_hls_base: String,
pub mediamtx_rtsp_base: String,
pub mediamtx_webrtc_base: String,
pub db_max_connections: u32,
pub recorder_enabled: bool,
pub mirror_recordings_dir: Option<PathBuf>,
pub anr_enabled: bool,
pub anr_interval_s: u64,
pub anr_max_gap_hours: i64,
pub anr_max_attempts: i64,
pub default_segment_seconds: i64,
pub default_retention_hours: i64,
pub default_camera_quota_bytes: u64,
pub default_record_audio: bool,
pub default_pre_roll_seconds: i64,
pub default_post_roll_seconds: i64,
pub indexer_interval_s: u64,
pub health_interval_s: u64,
pub retention_interval_s: u64,
pub api_host: String,
pub api_port: u16,
pub cors_origins: Vec<String>,
pub max_recordings_bytes: u64,
pub min_free_disk_bytes: u64,
pub notifier_interval_s: u64,
pub ai_enabled: bool,
pub ai_max_total_fps: f64,
pub default_ai_fps: f64,
pub default_ai_width: i64,
pub detection_retention_hours: i64,
pub snapshot_scheduler_enabled: bool,
pub snapshot_scheduler_interval_s: u64,
pub snapshot_retention_hours: i64,
pub schedule_check_interval_s: u64,
pub playback_session_ttl_minutes: i64,
pub max_playback_seconds: f64,
pub auth_enabled: bool,
pub session_ttl_hours: i64,
pub auth_cookie_secure: bool,
pub bootstrap_admin_user: Option<String>,
pub bootstrap_admin_password: Option<String>,
pub audit_retention_days: i64,
pub overlay_enabled: bool,
pub overlay_kind: String,
pub overlay_iface: Option<String>,
pub rclone_bin: String,
pub backup_enabled: bool,
pub backup_scheduler_interval_s: u64,
pub backup_job_timeout_s: u64,
pub backup_max_concurrent_jobs: usize,
pub archive_dir: PathBuf,
pub archive_max_bytes: u64,
pub archive_retention_hours: i64,
pub onvif_discovery_timeout_ms: u64,
pub onvif_request_timeout_ms: u64,
pub isapi_request_timeout_ms: u64,
pub smart_check_enabled: bool,
pub smart_devices: Vec<String>,
pub mdstat_check_enabled: bool,
pub smart_check_interval_s: u64,
pub readyz_min_recording_percent: f64,
pub live_transcode_engine: String,
pub vaapi_device: String,
pub site_id: Option<String>,
pub cp_url: Option<String>,
pub public_base_url: Option<String>,
pub cp_token: String,
pub cp_register_interval_s: u64,
pub cp_tls: Option<CpTlsCfg>,
pub registry_enabled: bool,
pub registry_urls: Vec<String>,
pub registry_refresh_s: u64,
pub registry_fetch_timeout_s: u64,
pub registry_trusted_keys: Vec<(String, String)>,
pub registry_allow_unverified: bool,
pub registry_allow_private: bool,
pub web_dir: Option<PathBuf>,
}Expand description
Runtime configuration, loaded from environment (see .env.example).
Fields§
§database_url: String§data_dir: PathBuf§recordings_dir: PathBuf§clips_dir: PathBuf§snapshots_dir: PathBuf§frames_dir: PathBuf§playback_dir: PathBufDirectory where segment-spanning HLS playback sessions are generated (one subdir per session).
ffmpeg_bin: String§ffprobe_bin: String§mediamtx_api_url: String§mediamtx_hls_base: String§mediamtx_rtsp_base: String§mediamtx_webrtc_base: String§db_max_connections: u32Max SQLite pool connections. Tunable per deployment: more absorbs bursts of concurrent requests (WAL serves reads concurrently; writes still serialize), at the cost of memory.
recorder_enabled: bool§mirror_recordings_dir: Option<PathBuf>Optional second recordings root for dual/mirror recording. When set, cameras with
mirror_enabled get a SECOND ffmpeg pipeline writing byte-identical segments here (a redundant
DVR copy on a separate volume). Empty/unset disables mirror recording entirely.
anr_enabled: boolMaster switch for ANR (Automatic Network Replenishment) edge re-fill: re-fetch missed footage
from a camera’s onboard storage to fill recording gaps. Cameras still need anr_enabled.
anr_interval_s: u64How often the ANR loop scans for pending gaps to fill (seconds).
anr_max_gap_hours: i64Ignore gaps older than this many hours (most cameras only retain recent onboard footage).
anr_max_attempts: i64Give up on a gap after this many fill attempts (marked failed).
default_segment_seconds: i64§default_retention_hours: i64§default_camera_quota_bytes: u64Default per-camera storage quota (bytes) applied when a camera is created without an explicit
storage_quota_bytes. 0 means no default quota (the camera’s quota is stored as NULL).
default_record_audio: boolDefault audio-recording toggle applied when a camera is created without an explicit
record_audio. When false (default) the recorder drops audio (video only).
default_pre_roll_seconds: i64Default pre-roll seconds applied when a camera is created without an explicit
pre_roll_seconds (event / scheduled_event recording). Clamped to 0..300 in handlers.
default_post_roll_seconds: i64Default post-roll seconds (the trigger recording window) applied when a camera is created
without an explicit post_roll_seconds. Clamped to 0..3600 in handlers.
indexer_interval_s: u64§health_interval_s: u64§retention_interval_s: u64§api_host: String§api_port: u16§cors_origins: Vec<String>§max_recordings_bytes: u64Soft cap on total recording footprint; oldest unlocked segments are pruned above this.
min_free_disk_bytes: u64Hard floor on free disk space; when free space drops below this, oldest unlocked segments are pruned regardless of age/size policy (protects the host from a full disk).
notifier_interval_s: u64How often the alert notifier polls for new events to deliver.
ai_enabled: boolMaster switch for AI frame sampling (Stage 2). Cameras still need an enabled AI task.
ai_max_total_fps: f64Global frame-sampling budget (frames/sec summed across all cameras); per-camera fps is reduced proportionally above this so adding AI cameras degrades fps instead of overloading.
default_ai_fps: f64§default_ai_width: i64§detection_retention_hours: i64How long detection rows are kept before the retention sweeper prunes them.
snapshot_scheduler_enabled: boolMaster switch for the background snapshot scheduler (interval live-frame captures).
snapshot_scheduler_interval_s: u64How often the scheduler ticks to look for due schedules (seconds).
snapshot_retention_hours: i64How long captured snapshots are kept before the retention sweeper prunes them. 0 = no pruning.
schedule_check_interval_s: u64How often the schedule watcher ticks to open/close recording windows for scheduled /
scheduled_event cameras (seconds). Windows are evaluated against the SERVER’s LOCAL timezone.
playback_session_ttl_minutes: i64How long a generated playback session (its HLS dir + the segment read-locks it holds) is retained before the cleanup sweeper removes the dir and releases its locks. Server time.
max_playback_seconds: f64Maximum playback session span (seconds); a longer requested range is rejected (HTTP 400).
auth_enabled: boolMaster switch for authentication + RBAC. When false, the API is open (dev/single-tenant LAN appliance default) and a synthetic admin principal is used. When true, the auth/admin surface requires a valid bearer token (session or API key) and enforces roles.
session_ttl_hours: i64Lifetime of an issued login session token.
Add Secure to the session cookie (require HTTPS). Default false for HTTP LAN/overlay
appliances; set true when the deployment is served over TLS.
bootstrap_admin_user: Option<String>Optional first-run admin bootstrap (only used when no users exist yet).
bootstrap_admin_password: Option<String>§audit_retention_days: i64How long kernel audit-log + generic-event rows are kept before retention prunes them.
overlay_enabled: boolWhether this deployment is reached through a WireGuard overlay (Tailscale / NetBird / wireguard) running as an external daemon on the host. The kernel does not manage the overlay; it only reports whether the configured interface is present + up so the dashboard can surface remote-access health. When false, the deployment is LAN-only.
overlay_kind: StringLabel for the overlay in use: tailscale | netbird | wireguard | none.
overlay_iface: Option<String>The overlay’s network interface to probe (e.g. tailscale0, wt0, wg0).
rclone_bin: StringPath to the rclone binary used for sftp/ftp/s3 remote backups. Local/NAS-mount backups use
std fs copy and never need it; remote backups degrade to a clear job error when it is missing.
backup_enabled: boolMaster switch for the background backup scheduler (scheduled policy jobs). On-demand archive export still works when this is false.
backup_scheduler_interval_s: u64How often the backup scheduler ticks to look for due policies (seconds).
backup_job_timeout_s: u64Hard timeout for a single backup job’s transfer (seconds); a job exceeding it is marked error.
backup_max_concurrent_jobs: usizeMaximum number of backup jobs running concurrently (a tokio Semaphore bounds the scheduler + manual triggers).
archive_dir: PathBufWhere on-demand archive (.zip) exports are written; also served at /media/archives.
archive_max_bytes: u64Maximum total source footprint (sum of segment sizes) for a single archive export; a larger selection is rejected (HTTP 400).
archive_retention_hours: i64How long archive exports + finished backup-job rows are kept before retention prunes them.
onvif_discovery_timeout_ms: u64How long the WS-Discovery probe listens for ProbeMatch replies (milliseconds).
onvif_request_timeout_ms: u64Per-request timeout for an ONVIF SOAP call (GetDeviceInformation, PTZ, etc.) in milliseconds.
isapi_request_timeout_ms: u64Per-request timeout for a HikVision ISAPI camera-config call (HTTP Digest) in milliseconds.
smart_check_enabled: boolRun periodic SMART self-assessment checks (smartctl -H) inside the health loop. Off by
default; needs smartmontools on PATH. Missing binary degrades to a one-time log + skip.
smart_devices: Vec<String>Block devices to query when SMART checks are enabled (e.g. /dev/sda,/dev/sdb).
mdstat_check_enabled: boolWatch /proc/mdstat (Linux md/RAID) and emit raid_degraded when an array shows a down member.
smart_check_interval_s: u64Cadence of the disk-health (SMART/RAID) check inside the health loop (seconds).
readyz_min_recording_percent: f64When > 0, /readyz also requires at least this percent of enabled cameras to be actively
recording (503 insufficient_recorders otherwise). 0 (default) keeps DB-connectivity-only.
live_transcode_engine: StringEncoder engine for the live preview transcode path: software (libx264, default), vaapi,
or nvenc. Unknown values warn and fall back to software.
vaapi_device: StringVAAPI render node used when live_transcode_engine = vaapi.
site_id: Option<String>Optional site identifier stamped onto outbox rows and surfaced at GET /api/v1/site for the
edge->cloud fleet uplink. Empty/unset = a single unnamed site.
cp_url: Option<String>Control-plane base URL for edge-side self-registration (HELDAR_CP_URL). Unset (default) = this
node never phones home; the fleet is opt-in. When set together with site_id and
public_base_url, the node POSTs its identity to the control plane on boot + on a heartbeat, so
the control plane drains it without any static config or restart.
public_base_url: Option<String>This node’s externally reachable base URL, as the control plane should address it
(HELDAR_PUBLIC_BASE_URL, e.g. its overlay/WireGuard address). Required for self-registration —
the node cannot infer it (it binds 0.0.0.0). Unset → self-registration parks.
cp_token: StringBearer credential the control plane presents when draining this node’s outbox
(HELDAR_CP_TOKEN). Empty (default) when this node runs with auth disabled (the LAN default);
when auth is enabled, set it to a valid API key the control plane may use.
cp_register_interval_s: u64Heartbeat cadence (seconds) for re-registration with the control plane
(HELDAR_CP_REGISTER_INTERVAL_S). Re-registration is idempotent, so the heartbeat also
re-teaches a control plane that restarted or lost its registry.
cp_tls: Option<CpTlsCfg>Optional mTLS material for talking to the control plane: this node’s client cert + key (to present when registering) and the CA that signed the control plane’s server cert (to verify it). Required as a set when the control plane enforces mTLS; unset = plain HTTP to the control plane (the LAN/overlay default).
registry_enabled: boolMaster switch for the plugin store’s remote-registry fetching. When false, the store shows only the bundled open catalog + locally installed plugins (fully offline). The bundled catalog is always available regardless.
registry_urls: Vec<String>Remote signed-catalog URLs to fetch (comma-separated). Default EMPTY — no phone-home; an operator (or the proprietary build) sets the official Straits-AI registry here to populate the proprietary/community shelves.
registry_refresh_s: u64How often the background loop refreshes remote registries (seconds).
registry_fetch_timeout_s: u64Per-fetch timeout for a remote catalog (seconds).
registry_trusted_keys: Vec<(String, String)>Operator-pinned extra trust anchors, key_id:base64pubkey comma-separated, added to the
compile-time pinned keys (for private registries).
registry_allow_unverified: boolWhen true, surface a remote registry’s entries even if its signature does not verify (badged unverified). Default false — fail closed.
registry_allow_private: boolWhen true, allow remote registry URLs that resolve to private/link-local addresses (default false; SSRF guard for the admin-configured fetch).
web_dir: Option<PathBuf>Directory holding the built React dashboard (apps/web/dist), served as a static SPA
fallback so the whole product is one binary at one URL. Resolved from HELDAR_WEB_DIR; when
unset it falls back to apps/web/dist relative to the binary CWD. None when neither path
exists — the server then runs API-only (no dashboard).
Implementations§
Trait Implementations§
Auto Trait Implementations§
impl Freeze for Config
impl RefUnwindSafe for Config
impl Send for Config
impl Sync for Config
impl Unpin for Config
impl UnsafeUnpin for Config
impl UnwindSafe for Config
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<A, B, T> HttpServerConnExec<A, B> for Twhere
B: Body,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more