Environment and files

Last updated applies to v1.9.3

The container's environment variables and which are live or one-time seeds, serving Shortlist from a subpath behind a reverse proxy, and the files it keeps under /config.

Everything else is set in the app and stored in its database; see the Settings reference.

Environment variables (container)

Variable Default Live or seed
PORT 5959 live
TZ Etc/UTC live
PUID / PGID 1000 live
SHORTLIST_CONFIG /config live
PLEX_URL, PLEX_TOKEN, TAUTULLI_URL, TAUTULLI_APIKEY, TMDB_APIKEY — seed once: copied into settings on first boot, ignored afterwards
LOG_LEVEL DEBUG seed once: initial value for the log.level setting; change it live in Settings → System
SHORTLIST_DRY_RUN unset live: when set (1/true), EVERY run is forced to dry-run. The app builds its clients and logs the would-be changes but writes NOTHING to Plex/plex.tv. Safe mode for a demo/test instance pointed at a real server (even a manual “Run now” can’t modify it)
SHORTLIST_ENABLE_DOCS unset live: when set (1), exposes the API docs at /api/docs and /api/openapi.json (off by default)
APP_BASE_PATH / live: serve the app from a subpath behind a reverse proxy, e.g. /shortlist. Read at startup, so the published image works unmodified — no rebuild. Accepts /shortlist or /shortlist/. The proxy just forwards; it does not need to strip the prefix. See Serving from a subpath.

Serving from a subpath

Set APP_BASE_PATH and point the proxy at the container. No rebuild, and no prefix-stripping middleware — the app recognises its own prefix, rewrites the asset URLs in the shell it serves, and publishes the prefix to the SPA so the router and API client use it too.

In the compose file from Getting started, add it under environment::

    environment:
      - APP_BASE_PATH=/shortlist

Traefik — router and service only:

http:
  routers:
    shortlist:
      rule: "Host(`media.example.com`) && PathPrefix(`/shortlist`)"
      service: shortlist
  services:
    shortlist:
      loadBalancer:
        servers:
          - url: "http://shortlist:5959/"

nginx — two blocks. location /shortlist on its own is a prefix match, so it would also swallow a sibling app at /shortlistings; ^~ /shortlist/ matches only the real subtree, and the exact-match block redirects the bare URL people actually type. Note there is no trailing slash on proxy_pass — that is what forwards the prefix intact:

location = /shortlist {
    return 308 /shortlist/;
}

location ^~ /shortlist/ {
    proxy_pass http://shortlist:5959;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

A proxy that strips the prefix anyway still works — an already-stripped path simply doesn’t match and is passed through untouched. That is also why the container’s own healthcheck, which requests an unprefixed /api/system/health on localhost, keeps working.

Leaving it unset serves the shell’s bytes exactly as they shipped.

Test through the proxy, at https://host/shortlist/. A blank page at the container’s own port — or at any URL without the prefix — is expected, not a fault: the app still answers there (that is how the healthcheck works), but the SPA it serves is built for the prefix and renders nothing outside it.

If it is blank through the proxy, check the container log first: it states the base path it is using at startup, and warns if APP_BASE_PATH held something it could not use (a query, a fragment, a space, an escaped or relative path) — in which case it ignores it and serves from the root, which on its own looks exactly like a proxy problem.

Files under /config

shortlist.db (SQLite: settings, users, runs, restriction snapshots, and the durable plex-account-id → slug map a row’s label is built from) · secret.key (Fernet, 600) · session.secret · logs/.

Edit this page on GitHub