# TMDB API v3 key (required) — https://www.themoviedb.org/settings/api TMDB_API_KEY=your_tmdb_v3_api_key # Fanart.tv API key (optional) — enables Fanart.tv as an alternative or preferred # image source for posters, logos, and backdrops. Without this key, all images are # sourced from TMDB. # https://fanart.tv/get-an-api-key/ FANART_API_KEY=your_fanart_api_key # At least one of OMDB_API_KEY, MDBLIST_API_KEY, or TRAKT_CLIENT_ID must be set for ratings. # MDBList is the preferred provider — it covers all 9 rating sources # (IMDb, RT Critics, RT Audience, Metacritic, Trakt, Letterboxd, MAL, # the MDBList aggregate score, and Roger Ebert). # OMDb only covers IMDb, RT Critics, and Metacritic. # MDBList API key (recommended) — https://mdblist.com/preferences/ MDBLIST_API_KEY=your_mdblist_api_key # OMDb API key (optional) — https://www.omdbapi.com/apikey.aspx # Required for IMDB episode ratings (MDBList does not support episode-level ratings) OMDB_API_KEY=your_omdb_api_key # Trakt Client ID (optional) — provides Trakt community ratings for movies, shows, # and episodes. Create an app at https://trakt.tv/oauth/applications to get a Client ID. # Can be used alongside or instead of MDBList/OMDb as a ratings provider. # TRAKT_CLIENT_ID=your_trakt_client_id # Directory to store cached posters and metadata CACHE_DIR=./cache # Directory to store the SQLite database (defaults to CACHE_DIR if unset) DB_DIR=./db # Address and port the server listens on LISTEN_ADDR=0.0.0.0:3000 # Minimum ratings cache lifetime in seconds (for brand-new films); scales up with film age RATINGS_STALE_SECS=86400 # Film age in seconds at which ratings are considered permanent and never rechecked (default: 1 year) RATINGS_MAX_AGE_SECS=31536000 # Base image cache lifetime in seconds (0 = never re-fetch) IMAGE_STALE_SECS=0 # JPEG output quality for generated images (1–100) IMAGE_QUALITY=85 # --- Auth --- # JWT signing secret (required) — 32-byte hex string # Generate with: openssl rand -hex 32 JWT_SECRET= # Set to false to allow non-HTTPS cookies (local development) # COOKIE_SECURE=true # Origin for CSRF protection on mutating requests (optional, e.g. https://posters.example.com) # CORS_ORIGIN= # Seed an admin user on first startup (optional — or use POST /api/auth/setup instead) # ADMIN_USERNAME=admin # ADMIN_PASSWORD=changeme # --- CDN --- # Enable content-addressed CDN redirects (set to true when behind Cloudflare or another CDN). # Authenticated poster requests return a 302 to a shared /c/{hash}/... URL so the CDN # deduplicates cache entries across users with identical settings. # Leave disabled for self-hosted setups without a CDN — the redirect is an extra round-trip # that provides no benefit when there is no caching layer in front of the origin. # ENABLE_CDN_REDIRECTS=true # Skip image file writes to disk (rendered posters and base source images). # Use when deployed behind a CDN like Cloudflare that caches responses at the edge. # The in-memory (moka) cache still handles short-term deduplication; the CDN handles # long-term caching. SQLite metadata (release dates, available rating sources) is # still written so cache keys and CDN TTLs can be computed without external API calls. # EXTERNAL_CACHE_ONLY=true # Force the free API key on or off. When set, the admin UI toggle is locked. # Omit to let admins control this from the settings page. # FREE_KEY_ENABLED=true