Menu
Nuvio Web docs

Configuration

There is no configuration file. The container is configured entirely through environment variables, and exactly one of them matters for a normal install.

ORIGIN

ORIGIN is the URL you actually browse to: scheme, host and port, no trailing slash.

-e ORIGIN=http://localhost:3000
-e ORIGIN=https://nuvio.example.com

Without it the server reconstructs its own origin from the request's Host header and assumes https://. Browse to a plain-HTTP address and that guess disagrees with the browser's Origin header, so SvelteKit's cross-site check rejects every write the app makes with 403 Cross-site remote requests are forbidden.

Only non-GET requests are checked, which makes this a confusing failure rather than an obvious one: the app still renders and reads fine, but nothing saves. Settings snap back, library toggles revert, progress never sticks. Set ORIGIN to exactly what is in the address bar and it goes away.

Serving over HTTPS on the default port needs none of this, because the assumed https:// already matches.

Behind a reverse proxy

Either set ORIGIN to the public URL, or let the proxy's own headers speak for it:

docker run -p 3000:3000 \
  -e PROTOCOL_HEADER=x-forwarded-proto \
  -e HOST_HEADER=x-forwarded-host \
  orochibraru/nuvio-web:latest
VariableDefaultWhen you need it
ORIGIN(unset)Always, unless the proxy headers below cover it
PROTOCOL_HEADERassumes httpsBehind a reverse proxy
HOST_HEADERthe Host headerBehind a proxy that rewrites it
PORT3000To listen on another port

Admin surface

The admin page is opt-in and off unless you name at least one administrator.

VariableDefaultWhat it does
NUVIO_ADMIN_EMAILSemptyAddresses allowed to reach /admin, comma or whitespace separated
NUVIO_DATA_DIRdataWhere the SQLite database lives (/app/data in the image)

Unset NUVIO_ADMIN_EMAILS means the admin page 404s for everybody. Addresses on this list can always sign in, even while the instance is locked, so a bad allowlist cannot lock you out of the page that fixes it. See The admin page.

Sessions

VariableDefaultWhat it does
NUVIO_SESSION_SECRETgenerated into <NUVIO_DATA_DIR>/session-secretSigns the session cookie, and (derived) encrypts the stored tokens

Sessions live on the server, in the SQLite database in NUVIO_DATA_DIR. The browser's cookie holds only a signed session id; the Nuvio access and refresh tokens stay in the database, encrypted (AES-256-GCM, key derived from the secret). That is what lets the server refresh a user's tokens, and sync their data, while no browser tab is open. A session unused for 30 days is dropped.

So mount a volume on the data directory: without one, every redeploy signs everyone out. The database must be writable, or nobody can sign in. Run one instance per data directory: token refreshes are serialized inside the process, and two processes sharing the database could each spend the same rotating refresh token.

Leave the variable unset on a single container: the first boot writes a random key to session-secret in the data directory (mode 0600) and every later boot reuses it. Set it explicitly (32+ characters, e.g. openssl rand -hex 32) when the secret must not live next to the database. A value shorter than 32 characters fails at boot. Changing or losing the key signs every user out (the stored tokens can no longer be decrypted); nothing else is lost.

Logging

VariableDefaultValues
NUVIO_LOG_LEVELdebug in dev, info in productiondebug info warn error
NUVIO_LOG_FORMATconsoleconsole, json

console is colorized and meant for docker logs. json emits one object per line for a log shipper. An unrecognised value fails at boot rather than being quietly ignored.

How variables are declared

Environment variables go through SvelteKit's explicit environment variables (experimental.explicitEnvironmentVariables). Each name is declared in src/env.ts and imported by name from $app/env/private; an undeclared name is not readable at all. They are deliberately non-static, so the container reads them at boot instead of having a build-time value inlined. Adding a variable means adding it to src/env.ts first.

This guide lives in the project repo: edit it there, and this page follows within a day.