Skip to content

Environment Variables

The variables below are grouped by area: core settings, performance tuning, authentication, AI, and the optional integrations.

Most settings are easier to change in the setup wizard and under Admin → Settings, and every field there can also be set as an environment variable with the same name. A value from the environment wins: the field in Admin → Settings then shows it and can’t be edited. .env.example lists only what a deployment needs before the app runs; this page covers common deployment and tuning settings. The secrets and deployment settings below are environment-only.

VariableRequiredDefaultDescription
DATABASE_PASSWORD / CACHE_PASSWORDYes, with the example compose file— (.env.example ships them empty)Passwords for the bundled PostgreSQL and Valkey. The compose file builds DATABASE_URL / CACHE_URL from them and refuses to start while either is empty. Use hex (openssl rand -hex 24): they end up in connection strings.
DATABASE_URLYes—PostgreSQL connection string (needs pgvector)
CACHE_URLYes—Disposable evictable cache Valkey URL. Set TASK_CACHE_URL separately for persistent task/shared coordination.
TASK_CACHE_URLYes—Persistent noeviction Valkey for BullMQ and shared coordination. No fallback to CACHE_URL; the same host and port are rejected even with different databases or credentials.
LUMASTRA_MASTER_KEYYes for multi-replicaauto-generated at <config>/master.keyEncrypts stored secrets and client credentials; derives JWT_SECRET when that is unset. Keep stable and back it up. Replicas that share neither this variable nor the /config volume generate different keys. See Configuration → Secrets at rest.
JWT_SECRETNoderived from the master keySigns access tokens for the apps and the public API (≥ 32 chars). Usually left unset.
NODE_ENVRecommended—Set production for deployments
ORIGINYes behind a reverse proxy or on HTTPS—Public origin (https://host). When it’s https, login cookies are always Secure. Without it, an app sign-in that sends no Origin header, through an inner proxy that reports http, can get a cookie without Secure on an HTTPS site. The host must match the address in the browser, or sign-in and other form posts fail with 403. Leave it unset for plain-HTTP access on your local network.
BASE_PATHNocontainer defaultWhere artwork / trickplay / the ffmpeg cache are written. Mount it as a shared RWX volume so web + worker share it.
PORTNo3000App listen port
BODY_SIZE_LIMITNo50M (image)Largest request body the app accepts (Node’s own default is 512K). Uploads fail with 413 if this, or your reverse proxy’s limit, is lower than the upload.
SETUP_UNLOCKNo—Set to 1 and restart to reopen /setup on a server with no administrator left. Applies only while no admin exists; remove it afterwards (the Security Self-Check warns while it is set).
PUBLIC_BASE_URLNo—Public origin used for absolute links the server builds without a request: the Trakt sign-in redirect, poster links in notification webhooks, and the Security Self-Check’s edge probes.
WORKER_MODESet by start scriptdisabled for webstart.sh runs web only; start-worker.sh sets enabled and DEDICATED_WORKER=true for the dedicated lean TypeScript task host. Run exactly one worker. Combined execution is unsupported.
INSTANCE_IDNohostname + random suffixNode name for the cluster/admin UI. The random suffix means the default is not stable across restarts (it avoids a Valkey key collision when the same hostname restarts in a new container); set it explicitly if you need a name that persists.
UPDATE_CHECK_ENABLEDNotrueOnce a day, read the Lumastra release list from api.github.com and tell admins about newer versions (red until installed for a security release). Usually set in Admin → Settings → General → Diagnostics instead; an environment value locks that switch. See What Lumastra sends where.
LICENSE_CHECK_IN_ENABLEDNotrueAbout once a week, send the install ID, Lumastra version and licence status code to lumastra.org so the project can count installs (pseudonymised counts, no IP address). Off skips only this check-in; renewal and the push relay token are unaffected. Usually set in Admin → Settings → General → Licensing or during setup; an environment value locks that switch. See What Lumastra sends where.
LICENSE_SERVER_CONTACT_ENABLEDNotrueOff: the install never contacts lumastra.org and runs on the free tier at once. Usually set in Admin → Settings → General → Licensing or during setup; an environment value locks that switch. See What Lumastra sends where.
LOG_LEVELNoinfodebug / info / warn / error
TZNoUTC (container default)The container’s time zone (e.g. Europe/Berlin, set in docker-compose.yml). Daily and weekly task triggers fire in this zone. There’s no separate in-app setting for it.
LUMASTRA_SKIP_PREFLIGHTNofalseBoot past preflight errors. The check still runs and logs its findings; this only stops it blocking startup.
TRICKPLAY_ENABLEDNofalseGenerate hover-preview thumbnail sprite sheets with ffmpeg
FFMPEG_PATHNo/config/bin/ffmpeg (image), ffmpeg otherwisePath to the ffmpeg binary (override to use a custom build)
FFPROBE_PATHNo/config/bin/ffprobe (image), ffprobe otherwisePath to the ffprobe binary
FFMPEG_AUTO_DOWNLOADNotrue (image)The image downloads jellyfin-ffmpeg into /config/bin on first start. Set false for offline installs and point the two paths above at your own binaries.

LIBRARY_ALLOWED_ROOTS accepts comma-separated absolute paths, such as /data,/media. Library folders and the folder browser must stay within those roots when set; when unset, any existing folder except / can be a library folder.

Also under Admin → Settings → Playback → Encoder & Hardware Tuning. A GPU must also be passed into the container; see GPU transcoding.

VariableDefaultDescription
GPU_ACCELERATIONnonenone, nvenc (NVIDIA), qsv (Intel), vaapi (Intel/AMD on Linux), amf (AMD on Windows, untested), videotoolbox (macOS bare metal, untested)
VAAPI_DEVICE/dev/dri/renderD128Render node for vaapi
QSV_DEVICE(auto)Device for qsv
NVENC_PRESET / NVENC_TUNE / NVENC_RC / NVENC_CQp4 / — / auto / 23NVENC tuning
AMF_QUALITYbalancedquality, balanced or speed
FFMPEG_TRANSCODE_DIR/tmp/lumastra-transcodeWorking directory for HLS segments; a tmpfs mount is faster
FFMPEG_INACTIVITY_TIMEOUT_SECONDS1800Remove a transcode nobody has used for this long
LUMASTRA_MAX_CONCURRENT_TRANSCODESCPU cores × 3, clamped 12–32Global active-job cap for this instance
FFMPEG_MAX_JOBS_PER_USER10Concurrent transcoding jobs one account can hold

If some accounts are untrusted, keep FFMPEG_MAX_JOBS_PER_USER well below LUMASTRA_MAX_CONCURRENT_TRANSCODES: one account can occupy up to its per-user limit in global slots. Configure both under Settings → Playback.

Mostly relevant for very large libraries or busy servers. See Performance tuning for guidance.

VariableDefaultDescription
LUMASTRA_SCAN_CONCURRENCY8Files processed in parallel per library scan. Keep ≤ the task DB pool; match it to NFS nconnect.
SCAN_ENRICH_INLINEfalsetrue fills TMDB metadata inline during scan (offline installs); off defers it to a background stage.
DISABLE_FILE_LIBRARY_SCANfalsetrue stops scheduled, manual and API-triggered library scans and file reconciliation. Leave it false if you trigger scans yourself. On inotify-less media (S3/Mountpoint), periodic scans ingest new files.
LUMASTRA_SCAN_STAT_BATCH_SIZE200Files stat()-ed per triage batch. Lower only for very slow storage.
LUMASTRA_DB_POOL_WEB_MAX8Postgres pool size for user-facing web/API requests
TASK_RUNTIME_LIVENESS_STALL_SECONDS600Worker liveness fails when the scheduler and consumer loops make no progress for this long
TASK_UPGRADE_PREPARED_TIMEOUT_MS900000A worker prepared for an upgrade resumes by itself after this long without stop or resume
LUMASTRA_DB_POOL_TASK_MAX7Postgres pool size for background tasks/scans (raise on a worker container)
LUMASTRA_DB_POOL_ADMIN_MAX4Postgres pool size for admin polling
UV_THREADPOOL_SIZE64*libuv threads for async file/DNS/crypto ops (*image default; Node’s is 4). Large so file I/O can’t starve DNS/DB connects.
LUMASTRA_FS_MAX_CONCURRENCY24Process-wide cap on concurrent guarded filesystem ops; kept under UV_THREADPOOL_SIZE so a slow NFS mount can’t saturate the pool.
LUMASTRA_FS_TIMEOUT_MS15000Per-op timeout for guarded filesystem ops (a hung NFS read fails fast instead of hanging the task).
LUMASTRA_CONCURRENCY_*variesPer-resource-class task caps (the heavy-job parallelism knobs): CPU auto floor(cores/2) 1–6, IO auto cores 4–12, INGEST 2, BULK 3, EMBEDDING 1, ANALYSIS 1, MAINTENANCE 1, DISCOVERY 1. Under per-task queues INGEST+BULK fold into IO and ANALYSIS into CPU (caps summed).
LUMASTRA_LOW_RAM_MODEfalseCaps the Node.js heap and reduces Valkey connection overhead on the worker. Recommended on constrained hosts (Raspberry Pi-class, <4 GB). See Memory.

Pool totals are per instance; the sum across all replicas must stay under Postgres’ max_connections (default 100). Raise max_connections if you scale pools or replicas. Also set shm_size: 1gb on the Postgres container (compose): the 64 MB default /dev/shm causes parallel-query failures on large libraries. See Performance tuning.

VariableDefaultDescription
WORKER_MODEdisabled for webSet by the role start script: web submits work; the dedicated worker runs tasks/plugins and supervises its Rust watcher child.
LUMASTRA_WATCH_NETWORK_RECONCILE_SECS900Seconds between network-mount reconciliations by the Rust watcher. Network mounts are always watched; 0 disables only periodic reconciliation.
LUMASTRA_ORCHESTRATOR_LEADER_TTL_MS15000Advanced (rarely tuned). Per-class leader-lock TTL. Raise to 30000 on a single heavy worker to avoid leadership flapping under cold-start backlog.
LUMASTRA_ORCHESTRATOR_LEADER_RENEW_MS5000Advanced. Leader-lock renew cadence (must be < TTL).
LUMASTRA_RUN_STATE_TTL_ACTIVE_MS900000Advanced. Zombie self-heal window: a crashed run is reclaimed ~15 min after its last heartbeat.
PREVIEW_CACHE_DIR/config/cache/previewWhere hover-preview clips are cached as small content-addressed VOD artifacts. On a multi-instance web tier, put this on shared storage (it rides the config volume by default) so any instance can serve a finished preview from disk. See Zero-downtime updates › Hover previews. Single-instance needs nothing.
PREVIEW_CACHE_ENABLEDtrueSet false to disable the hover-preview disk cache entirely (every hover re-transcodes on demand).

The Rust watcher is the only file watcher, including on bare metal and in development. Remove LUMASTRA_WATCHER_IMPLEMENTATION and LUMASTRA_WATCH_NETWORK_FS=false from older configurations: they are no longer supported and produce a startup warning. Network mounts are watched and reconciled every 900 seconds (15 minutes) by default.

The three methods coexist. See Authentication. ADMIN_GROUPS applies to both forward auth and OIDC.

VariableRequiredDefaultDescription
FORWARD_AUTH_ENABLEDFor forward authfalseRead identity headers at all. Off: ignored from every peer. Upgrading forward-auth installs must set true. Environment only: Admin → Settings shows it read-only, and a value in settings.json is ignored (logged at startup)
TRUSTED_PROXY_IPSBehind a proxy(unset → fail-closed)Addresses of your proxies, allowed to set identity headers (with FORWARD_AUTH_ENABLED) and X-Forwarded-For. List every proxy that adds to X-Forwarded-For, and only proxies: a LAN range lets every device in it choose its client IP and, with forward auth on, sign in as anyone. IPv4 ranges wider than /24 are reported as a warning; IPv6 ranges are not supported. See Reverse proxy
LUMASTRA_TRUST_ANY_PROXYNofalseTrust any peer’s identity headers (single host only)
USERHEADERNoX-Forwarded-UserHeader carrying the authenticated username
GROUPHEADERNoX-Forwarded-GroupsHeader carrying the user’s groups (|- or comma-separated)
NAMEHEADERNoX-Authentik-NameHeader carrying the display name; empty ignores it
FORWARD_AUTH_GROUPS_ALWAYS_SENTNofalseThe proxy sends GROUPHEADER on every signed-in request, so a missing header means “no groups” (stored groups are cleared, admin removed). Needed behind nginx auth_request, which drops empty headers
ADMIN_GROUPSNoadminGroups whose members are administrators (case-insensitive). Also used by OIDC. Set it before the first SSO sign-in
WATCH_PERMISSION_GROUPSNoadmin,stream-monitorsGroups that see every user’s streaming sessions
LIVETV_GROUPSNolivetv,adminGroups with Live TV access
ARR_MANAGER_GROUPSNoarrmanager,adminGroups (besides admins) that see the debug panel and connected service URLs
PUBLIC_AUTHURLNo—Link to your identity provider’s account page, shown in Settings when users don’t use built-in login
PUBLIC_LOGOUTURLNo—Where “Sign out” sends the browser, e.g. the identity provider’s logout URL
DEFAULT_USERNo (dev only)adminUnder npm run dev, the user assumed when no header is present. With Jellyfin connected, also the Jellyfin account used for some metadata lookups
PROTOCOL_HEADERBehind TLS proxyx-forwarded-protoHeader the app reads to learn the external scheme for the addresses it builds. Lumastra reads X-Forwarded-Proto for the session cookie’s Secure flag on its own; set this when your proxy sends the scheme in another header.
HOST_HEADERBehind a proxyx-forwarded-hostHeader the app reads to learn the external host
VariableRequiredDefaultDescription
AUTH_NATIVE_LOGIN_ENABLEDNofalseEnable username/password login. The setup wizard turns it on when it creates the first admin. .env.example sets it to true, because the startup check refuses to boot with no sign-in method configured; while it is set there, the switch in Admin → Settings is read-only
NATIVE_AUTH_SESSION_TTL_DAYSNo30Session-cookie lifetime in days
VariableRequiredDefaultDescription
AUTH_OIDC_ENABLEDFor OIDCfalseEnable the OIDC client (also needs issuer + client ID)
AUTH_OIDC_ISSUERFor OIDC—Provider issuer / discovery base URL
AUTH_OIDC_CLIENT_IDFor OIDC—OAuth client ID
AUTH_OIDC_CLIENT_SECRETNo—Client secret (empty = public/PKCE-only client)
AUTH_OIDC_SCOPESNoopenid profile emailSpace-separated scopes (must include openid)
AUTH_OIDC_GROUPS_CLAIMNogroupsClaim (dot-path ok) carrying groups, matched vs ADMIN_GROUPS
AUTH_OIDC_PROVIDER_NAMENoSingle Sign-On”Sign in with…” button label
AUTH_OIDC_REDIRECT_URINo(auto)Override the …/auth/oidc/callback redirect URI
AUTH_OIDC_LINK_BY_VERIFIED_EMAILNotrueAuto-link to an existing account on a verified-email match
AUTH_OIDC_LINK_BY_USERNAMENofalseAuto-link by username (less safe; for migration)
AUTH_OIDC_USERINFONofalseFetch UserInfo when groups/email absent from the ID token
AUTH_OIDC_ALLOW_INSECURENofalseAllow a non-HTTPS issuer (test IdPs only)
AUTH_OIDC_BACKCHANNEL_LOGOUT_CASCADENofalseOn a user-wide (sub) back-channel logout, also revoke the user’s device tokens

Setting any of these keys sends library descriptions and user prompts to that provider. See What Lumastra sends where before you do. ANTHROPIC_API_KEY, ASSISTANT_PROVIDER, OPENAI_BASE_URL, ANTHROPIC_BASE_URL and EMBEDDING_BASE_URL (custom or on-premise endpoints) are documented in the admin Settings UI under AI assistant.

VariableRequiredDefaultDescription
OPENAI_API_KEYNo—OpenAI embeddings (used when VOYAGE_API_KEY is unset)
VOYAGE_API_KEYNo—Voyage AI embeddings; wins when both keys are set
EMBEDDING_BASE_URL / EMBEDDING_API_KEYNo—Custom OpenAI-compatible embedding endpoint (e.g. Ollama). Needs both; there is no fallback to OPENAI_API_KEY
EMBEDDING_MODELNo(auto-detect)e.g. text-embedding-3-small, voyage-3-large
EMBEDDING_DIMENSIONSNo0 (auto)Vector width, fixed when the database is created (must match the model). Changing it later is not migrated: startup stops with a column-width mismatch
OPENAI_CHAT_API_KEYNo—Key for the assistant’s OpenAI-compatible chat backend (any non-empty value for a local server)
OPENAI_CHAT_MODELNogpt-4o-miniChat model for the assistant
ANTHROPIC_API_KEY / ANTHROPIC_CHAT_MODELNo— / claude-opus-4-8Claude as the assistant’s chat backend
ASSISTANT_PROVIDERNoautoauto uses Claude when ANTHROPIC_API_KEY is set and OPENAI_CHAT_API_KEY is not

For the sonic music features. The sidecar (ghcr.io/lumastra/lumastra-sonic-embedder) runs Microsoft’s CLAP-2023 model via the msclap package; its weights download from HuggingFace (microsoft/msclap) at runtime, not bundled by Lumastra (review the model card for the weight terms).

VariableSet onRequiredDefaultDescription
SONIC_EMBEDDER_URLapp + workerFor sonic—HTTP URL of the embedder sidecar (e.g. http://lumastra-sonic-embedder:8000). Required by any FEATURE_MUSIC_SONIC*.
SONIC_READER_PASSWORD.env (compose)For sonic—Password of the sidecar’s read-only database role, interpolated by the example compose file’s sonic profile
SONIC_EMBEDDER_THREADSsidecarNo(all cores)PyTorch CPU thread cap. Keep it modest (e.g. 4) on shared hardware so playback stays responsive
MODEL_IDsidecarNomsclap-2023Model identifier recorded with the embeddings
HF_HOMEsidecarNo/app/.cache/huggingfaceHuggingFace cache for the downloaded CLAP weights. Mount a persistent volume here to download once
SONIC_MODEL_FPsidecarNo—Absolute in-container path to a local CLAP weights .pth. Set it (with a read-only mount) for air-gapped / offline installs; the sidecar then loads locally and never reaches HuggingFace
SONIC_MEMORY_LIMIT_MBsidecarNocontainer limitMemory the sidecar plans its jobs with. Normally leave unset; see Sonic sidecar memory
SONIC_MEMORY_RESERVE_MBsidecarNomax(512, 10 % of limit)Headroom kept out of the job budget
SONIC_MAX_CONCURRENT_JOBSsidecarNoCPUs ÷ threads, max 2Heavy jobs at once; the memory gate may run fewer
SONIC_ADMISSION_QUEUE_TIMEOUT_SECsidecarNo120How long a request may wait for memory before the sidecar answers 429
SONIC_TEXT_ENCODERsidecarNoautowarm, lazy or auto (warm at 8 GiB or more). Only Sound Search uses it
SONIC_TEXT_ENCODER_IDLE_SECsidecarNo900Idle seconds before an on-demand text encoder is unloaded
MALLOC_ARENA_MAXsidecarNo2 (image)glibc malloc arenas; fewer hold on to less freed memory
SONIC_ANALYZE_MAX_DURATION_SECsidecarNo7200Longest file the sidecar analyses; longer ones are refused before decoding

All optional; defaults render the bundled Lumastra identity. Custom name, logos, description and background take effect only with the custom-branding licence module (see Editions & Licensing); the two colours always apply. Logo values are http(s) URLs or paths starting with /, such as /custom/logo.png.

VariableDefaultDescription
APP_NAMELumastraApp name in the header, browser title, and installed PWA
APP_DESCRIPTIONMedia DashboardMeta description (SEO + PWA manifest)
APP_LOGO_SMALL(bundled)Square navbar logo
APP_LOGO_FULL(bundled)Wide logo for splash / header
APP_LOGO_PLAY(bundled)Small play-button icon on cards
APP_BACKGROUND_IMAGE(bundled)Full-page background wallpaper
APP_THEME_COLOR#7c3aedTints the installed PWA titlebar + the mobile browser address bar
APP_BACKGROUND_COLOR#0f172aPWA splash-screen background shown while the app boots
WEB_APP_INSTALL_HINTtrue”Get the app” hint for Safari on iPhone/iPad (HTTPS only); false hides it
ASSISTANT_NAMEAssistantAI assistant display name; requires FEATURE_AI_ASSISTANT
ASSISTANT_AVATAR(bundled)AI assistant avatar; requires FEATURE_AI_ASSISTANT

Mount a folder of your own images read-only at /app/build/client/custom and reference them as /custom/<file> in the variables above:

services:
lumastra:
volumes:
- /path/to/my-branding:/app/build/client/custom:ro
environment:
- APP_NAME=MyDashboard
- APP_LOGO_SMALL=/custom/my-button.png # ~400×400, square
- APP_LOGO_FULL=/custom/my-fulllogo.png # ~1000×300, wide
- APP_LOGO_PLAY=/custom/my-play-24.png # 24×24
- APP_BACKGROUND_IMAGE=/custom/my-background.jpg # 1920×1080 or larger

The default logos served at /branding/… and the PWA install icons aren’t env vars. Override the bundled files by mounting your own over them:

Mount overWhat it replaces
/app/build/client/branding/lumastra-icon.svgDefault small logo / icon
/app/build/client/branding/lumastra-logo-horizontal-ondark.svgDefault full logo
/app/build/client/favicon.pngBrowser favicon (48×48)
/app/build/client/icon-192.png, icon-512.png (+ -maskable)PWA install icons
/app/build/client/apple-touch-icon.pngiOS home-screen icon

A few in-app brand usages (the About dialog, for one) are compiled into content-hashed assets and keep the Lumastra identity. See Editions & Licensing for what a full rebrand of a fork involves.

Three JSON-array variables customise the footer, the sidebar and the avatar menu. Each entry takes label, url and optional external (default true; set false for in-app routes). Sidebar and avatar-menu entries also take icon (a Heroicons name, or a path such as /custom/icon.svg from the custom asset folder). Sidebar entries also accept groups, a list of group names that must match for the entry to show; the special group __ADMIN__ means “admins only”.

VariableEffect
FOOTER_LINKSLinks in the footer bar, which shows only with SHOW_FOOTER=true (default false)
SIDEBAR_LINKSReplaces the whole sidebar / dock navigation, so include Home and Browse yourself
USER_MENU_LINKSExtra links in the avatar menu (empty by default; Settings and Sign out are always there)
Terminal window
SHOW_FOOTER=true
FOOTER_LINKS='[
{"id":"docs","label":"Help","url":"https://wiki.example.com"},
{"id":"quickconnect","label":"Quick Connect"}
]'
SIDEBAR_LINKS='[
{"label":"Home","url":"/","icon":"home","external":false},
{"label":"Browse","url":"/browse","icon":"/icons/browse.svg","external":false},
{"label":"Admin","url":"/admin","icon":"cog-6-tooth","external":false,"groups":["__ADMIN__"]}
]'
USER_MENU_LINKS='[
{"label":"Settings","url":"https://auth.example.com","icon":"cog-6-tooth"},
{"label":"Logout","url":"https://auth.example.com/logout","icon":"arrow-right-on-rectangle"}
]'

Footer entries carry an id; the special id quickconnect opens the Jellyfin Quick Connect dialog, needs no url and shows only when Jellyfin is connected. SIDEBAR_SECTIONS (a JSON array of {"id","label","icon","collapsed"}) defines collapsible groups; a sidebar entry joins one with "section":"<id>". The same links can be managed from the admin UI under Settings → Homepage & navigation, which is the easier route if you don’t manage configuration as code.

Each key below enables outbound calls to that service; what each one receives is listed in What Lumastra sends where. The iOS push settings (FEATURE_PUSH_NOTIFICATIONS, PUSH_RELAY_URL, PUSH_RELAY_TOKEN, PUSH_TRANSPORT, APNS_KEY_P8) live under Admin → Settings → Access → Push Notifications; the default relay is run by the Lumastra maintainer and is covered on that page.

VariableDescription
TMDB_API_KEYMetadata, images, search
MDBLIST_API_KEYAggregated ratings + keyword tags
LASTFM_API_KEYMusic popularity
DISCOGS_TOKENArtist / album enrichment
JELLYFINURL / JELLYFINAPIKEYJellyfin metadata and optional background sync (the /j compat API needs neither)
PUBLIC_JELLYFINURLPublic Jellyfin address for links users click (homepage button, Quick Connect hint). Environment only
AUDIOURL / AUDIOAPIKEYAudiobookShelf: the key needs admin rights so per-listener keys can be minted. See Audiobooks
PUBLIC_AUDIOBOOKURLPublic AudiobookShelf address for the “open in AudiobookShelf” button. Environment only
KAVITAURL / KAVITAAPIKEYKavita (books / manga / comics)
PUBLIC_KAVITAURLPublic Kavita address for links from search results. Environment only
ANIDB_CLIENT / ANIDB_CLIENT_VERRegistered AniDB client name and version, for libraries that use the AniDB metadata provider. The value in the plugin settings wins
SONARRURL / SONARRAPIKEYSonarr (TV calendar)
RADARRURL / RADARRAPIKEYRadarr (movie calendar)
SEERRURL / SEERRAPIKEYSeerr (requests)
VariableDefaultDescription
AUDIOBOOK_REMUX_MAX_PER_USER2Concurrent on-the-fly remuxes one listener may hold on a single instance. Each is an ffmpeg process started at a requested offset, and dragging the scrubber can ask for several in a second. 0 disables the cap.

See Audiobooks for the rest of the setup.

Most Live TV settings are managed in the admin UI and covered in the Live TV guide. The egress/privacy variable:

VariableDefaultDescription
LIVETV_SOURCEstandalonestandalone uses Lumastra’s own Live TV stack; disabled turns the subsystem off entirely.
STREAM_PROXY_URL(unset)Base URL of the Live TV stream proxy that pulls and re-serves channel streams.
STREAM_PROXY_SECRET(unset)Shared secret authenticating Lumastra to the stream proxy. Set the same value on both; the proxy refuses to start without it.
LIVETV_CAP_FALLBACKsourceWhen a requested quality can’t be produced: source serves the original, refuse fails playback
LIVETV_UPSTREAM_PROXY_URL(unset → direct)Forward HTTP CONNECT proxy for all outbound Live TV traffic to the source (M3U/XMLTV import, channel logos, Xtream validation, and live stream pulls), for networks that require an outbound proxy. Inline credentials supported. Must be set on the app, worker, and stream-proxy containers (each reads it independently). Fail-closed. See the Live TV guide and the HTTPS-stream caveat.

What users on the same server can see about each other. See Sharing & privacy for the full picture.

VariableDefaultDescription
SOCIAL_DEFAULT_AUDIENCEautoWho can see each other’s audiobook activity: auto, household (everyone on the server), or groups. auto uses groups when SOCIAL_TRUST_GROUPS names any, otherwise household.
SOCIAL_TRUST_GROUPSemptyGroups for groups mode; two users see each other only if they share one named here. Separate groups stay separate. Empty means nobody, not everyone.
SOCIAL_REVIEW_GROUPSemptyWho may write community reviews. Empty means everyone, the opposite of SOCIAL_TRUST_GROUPS.
FEATURE_SESSIONS_PUBLICtrueLets non-admins see other users’ active sessions. Server-wide, not group-scoped. Requires FEATURE_SESSIONS.
FEATURE_SESSIONS_DEVICE_INFO_PUBLICfalseAlso exposes client and browser names on those sessions.

Users override all of this downward from Settings → Privacy; a per-book hide is stronger still. Nothing here can force a user to share.

Extension loading and the signed-install trust gate. Full context in Plugins & extensions.

VariableDefaultWhat
PLUGINS_ENABLEDtrueSet false to load no external plugins at all
PLUGINS_EXTERNAL_DIR/app/pluginsWhere plugin directories live
PLUGIN_TRUSTED_KEYS(unset)keyId:base64Spki list, Ed25519. Required for signed install
PLUGINS_EXTERNAL_INSTALL_ENABLEDtrueSet false to remove the remote-install endpoint entirely
PLUGINS_REQUIRE_REGISTRYfalseSet true to load only signed, registry-managed plugins
PLUGIN_INSTALL_ALLOW_PRIVATEfalseAllow manifest fetches from private IPs. Development only

Install resource caps below bound size and count only; they can never grant trust: PLUGIN_INSTALL_MAX_MANIFEST_BYTES (64 KiB), PLUGIN_INSTALL_MAX_BUNDLE_BYTES (8 MiB), PLUGIN_INSTALL_MAX_EXTRACTED_BYTES (32 MiB), PLUGIN_INSTALL_MAX_FILE_BYTES (8 MiB), PLUGIN_INSTALL_MAX_ENTRIES (2048), PLUGIN_INSTALL_FETCH_TIMEOUT_MS (15000).

Every FEATURE_* flag, its default and what it gates is listed in FEATURE_* flags; FEATURE_SHARED_QUEUE_CONNECTION defaults to LUMASTRA_LOW_RAM_MODE’s value and can be set independently.