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.
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
| Variable | Default | Description |
|---|---|---|
LISTENUP_HOME | ~/ListenUp | Data directory: the SQLite database, secrets.properties, cover art, and the scan spool. Use an absolute path; ~ is read literally, not shell-expanded. |
PORT | 8080 | HTTP listen port. Note the variable is PORT, not LISTENUP_PORT. |
LISTENUP_SERVER_NAME | ListenUp | Instance display name, shown on the public invite landing page. |
LISTENUP_DATA_DIR_LOCK | true | Takes 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.
| Variable | Default | Description |
|---|---|---|
LISTENUP_JWT_SECRET | generated | HS256 signing secret, at least 32 bytes. An explicit value that's the committed default, or shorter than 32 bytes, fails startup. |
LISTENUP_REFRESH_PEPPER | generated | HMAC-SHA-256 pepper for refresh tokens, at least 32 bytes. Rotating it invalidates all stored hashes, forcing every user to re-authenticate. |
Registration
| Variable | Default | Description |
|---|---|---|
LISTENUP_REGISTRATION_POLICY | APPROVAL_QUEUE | How new sign-ups are handled. |
Scanner & library
| Variable | Default | Description |
|---|---|---|
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_SIZE | 1000 | Maximum embedded-artwork covers held in the in-memory LRU cache. |
LISTENUP_SCAN_RESCAN_ON_STARTUP | true | Re-walk every library once on startup. |
LISTENUP_SCAN_PERIODIC_RESCAN_INTERVAL | 6h | Periodic 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.
| Variable | Default | Description |
|---|---|---|
LISTENUP_LOG_LEVEL | INFO | Default log level. |
Seed & development
| Variable | Default | Description |
|---|---|---|
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, notLISTENUP_PORT. The HTTP port is the one unprefixed variable. - Paths must be absolute.
LISTENUP_HOMEreads~literally (it isn’t shell-expanded), so write the full path. - Durations are Kotlin
Durationstrings like6hor30m.0disables the periodic rescan while the live file watcher keeps running. - Invalid values fail fast. A bad
LISTENUP_METADATA_PRECEDENCEtoken, or a JWT secret under 32 bytes, stops startup rather than running misconfigured.