Server Setup

Configuration

ListenUp is configured entirely through environment variables, and everything has a sensible default. Toggle the settings you want and copy a ready-to-run config.

~3 min

A bare install runs with nothing set. Set variables however you run the server: docker run -e, a Compose environment: block, a systemd unit, or your shell. Secrets are the exception: leave them unset and ListenUp generates secure values on first boot.

Config builder#

Flip a switch to include a variable, set its value, and your config assembles live. Switch between Compose, docker run, and .env formats, and click any variable name to copy it.

Core & runtime

VariableDefaultDescription
LISTENUP_HOME~/ListenUpData directory: the SQLite database, secrets.properties, cover art, and the scan spool. Use an absolute path; ~ is read literally, not shell-expanded.
PORT8080HTTP listen port. Note the variable is PORT, not LISTENUP_PORT.
LISTENUP_SERVER_NAMEListenUpInstance display name, shown on the public invite landing page.
LISTENUP_DATA_DIR_LOCKtrueTakes an exclusive OS lock on the data directory so two server processes can't share one home and race the scan spool.

Secrets

Leave these unset and ListenUp generates secure values on first boot, persisting them to secrets.properties. Back up that file.

VariableDefaultDescription
LISTENUP_JWT_SECRETgeneratedHS256 signing secret, at least 32 bytes. An explicit value that's the committed default, or shorter than 32 bytes, fails startup.
LISTENUP_REFRESH_PEPPERgeneratedHMAC-SHA-256 pepper for refresh tokens, at least 32 bytes. Rotating it invalidates all stored hashes, forcing every user to re-authenticate.

Registration

VariableDefaultDescription
LISTENUP_REGISTRATION_POLICYAPPROVAL_QUEUEHow new sign-ups are handled.

Scanner & library

VariableDefaultDescription
LISTENUP_LIBRARY_PATH(empty)Absolute folders used to seed the singleton library on first boot. Delimited by the OS path separator (: on Unix, ; on Windows).
LISTENUP_METADATA_PRECEDENCE(default order)Comma-separated, highest priority first. An invalid token fails startup.
LISTENUP_EMBEDDED_COVER_CACHE_SIZE1000Maximum embedded-artwork covers held in the in-memory LRU cache.
LISTENUP_SCAN_RESCAN_ON_STARTUPtrueRe-walk every library once on startup.
LISTENUP_SCAN_PERIODIC_RESCAN_INTERVAL6hPeriodic full-rescan backstop, as a Kotlin Duration (e.g. 30m). 0 or blank disables it; the live file watcher keeps running.

Logging

For a per-package override, set LISTENUP_LOG_LEVEL_<prefix> (underscores become dots; the longest matching prefix wins), e.g. LISTENUP_LOG_LEVEL_com_calypsan_listenup_server_scanner=DEBUG.

VariableDefaultDescription
LISTENUP_LOG_LEVELINFODefault log level.

Seed & development

VariableDefaultDescription
LISTENUP_SEED_PROFILE(empty)Selects a startup seed profile (demo data). Intended for development; only sort of works right now.

Secrets generate in your browser for convenience, but you rarely need to set them. Leaving LISTENUP_JWT_SECRET and LISTENUP_REFRESH_PEPPER unset lets ListenUp create and persist them to secrets.properties. Back up that file: lose the JWT secret and everyone is logged out; rotate the pepper and everyone must sign in again.

A few specifics worth knowing#

  • It’s PORT, not LISTENUP_PORT. The HTTP port is the one unprefixed variable.
  • Paths must be absolute. LISTENUP_HOME reads ~ literally (it isn’t shell-expanded), so write the full path.
  • Durations are Kotlin Duration strings like 6h or 30m. 0 disables the periodic rescan while the live file watcher keeps running.
  • Invalid values fail fast. A bad LISTENUP_METADATA_PRECEDENCE token, or a JWT secret under 32 bytes, stops startup rather than running misconfigured.

Last updated June 27, 2026