Configuratie
Alles is een Spring-property en elke property is te overschrijven via omgevingsvariabelen
(relaxed binding: app.ister.server.name ⇒ APP_ISTER_SERVER_NAME). Veel instellingen hebben
daarnaast een eigen korte env var, hieronder vermeld. De standaardwaarden zijn verstandig voor
een single-node thuisopstelling.
Kernservices
| Instelling | Env var | Standaard | Opmerkingen |
|---|---|---|---|
| Databasehost / poort / naam | DB_HOST / DB_PATH / DB_NAME | localhost / 5432 / ister | PostgreSQL |
| Database-inloggegevens | DB_USER / DB_PASSWORD | ister / ister | wijzig dit in productie |
| Connectionpool | DB_POOL_SIZE | 20 | afspelen waaiert uit naar veel gelijktijdige queries |
| Connectie-timeout (ms) | DB_CONNECTION_TIMEOUT | 10000 | hoe lang een thread op een poolverbinding wacht voordat het faalt |
| RabbitMQ | SPRING_RABBITMQ_HOST / _PORT / _USERNAME / _PASSWORD | localhost, 5672, user/password | poort valt terug op de RabbitMQ-standaard 5672 |
| OIDC-issuer | OIDC_URL | http://keycloak:8060/realms/Ister | Keycloak-compatibel; de standaard matcht de meegeleverde dev-Keycloak. Productie: bijv. https://keycloak.example.com/realms/Home |
| OIDC-audience | OIDC_AUDIENCE | (leeg) | Optioneel. Indien gezet moet een access-token de waarde in aud hebben of als azp dragen (de client-id, bijv. ister). Leeg = alleen issuer en handtekening, dus tokens voor andere clients in dezelfde realm worden ook geaccepteerd. |
Identiteit en paden
| Instelling | Env var | Standaard | Opmerkingen |
|---|---|---|---|
app.ister.server.name | APP_ISTER_SERVER_NAME | Test server | moet uniek zijn per node |
app.ister.server.url | APP_ISTER_SERVER_URL | http://localhost:8080 | hoe clients én andere nodes deze node bereiken |
app.ister.cluster.name | APP_ISTER_CLUSTER_NAME | de servernaam | dezelfde waarde op elke node van een cluster |
| Cachemap | CACHE_DIR | /cache/ | afbeeldingen, podcastdownloads |
| Tijdelijke map | TMP_DIR | /tmp/ister/ | HLS-transcode-uitvoer |
app.ister.server.websocket.allowed-origins | APP_ISTER_SERVER_WEBSOCKET_ALLOWED_ORIGINS | leeg | extra origins die de GraphQL-websocket-handshake accepteert. De publieke host uit app.ister.server.url is automatisch toegestaan (beide schema's, elke poort), dus dit is alleen nodig als de server onder een tweede naam wordt aangeboden. * staat elke origin toe. |
Objectopslag (S3)
Zie Objectopslag. Connecties zijn geïndexeerde lijsten (APP_ISTER_S3_CONNECTIONS_0_NAME, …).
| Instelling | Env var | Standaard | Opmerkingen |
|---|---|---|---|
app.ister.s3.connections[n].name | waar directories en de gedeelde opslag naar verwijzen | ||
app.ister.s3.connections[n].endpoint | leeg | leeg = AWS; http://garage:3900 voor een zelfgehoste server | |
app.ister.s3.connections[n].region | us-east-1 | ||
app.ister.s3.connections[n].bucket | één bucket per connectie | ||
app.ister.s3.connections[n].path-style | true | path-style-adressering, nodig voor MinIO/Garage/Ceph | |
app.ister.s3.connections[n].access-key / .secret-key | leeg | leeg = de standaard credential-keten van de SDK (AWS) | |
app.ister.disk.directories[n].s3-connection / .prefix | maakt de directory een S3-directory (geen path); prefix optioneel | ||
app.ister.s3.ffmpeg-direct | S3_FFMPEG_DIRECT | false | true: ffmpeg leest presigned S3-URL's in plaats van de eigen proxy van de node |
app.ister.s3.presign-ttl | S3_PRESIGN_TTL | 2h | levensduur van die URL's; houd hem boven de langste pass |
app.ister.server.self-url | SELF_URL | http://127.0.0.1:<server.port> | waar de node zijn eigen proxy bereikt voor ffmpeg; houd dit op loopback achter een gateway met request-timeouts |
app.ister.s3.local-copy-dir / .local-copy-max-bytes | S3_LOCAL_COPY_DIR / S3_LOCAL_COPY_MAX_BYTES | <tmp-dir>/s3-scratch/ / 2 GiB | LRU-cache van objecten die als lokaal bestand gelezen moeten worden (epub/cbz/pdf, OCR) |
app.ister.server.cache-s3-connection / .cache-s3-prefix | CACHE_S3_CONNECTION / CACHE_S3_PREFIX | leeg / cache | de cluster-gedeelde cache; vervangt CACHE_DIR voor nieuwe afgeleide bestanden |
app.ister.server.tmp-s3-connection / .tmp-s3-prefix | TMP_S3_CONNECTION / TMP_S3_PREFIX | leeg / tmp | de cluster-gedeelde transcode-opslag; TMP_DIR blijft de lokale encodeer-scratch |
Metadata en talen
| Instelling | Env var | Standaard | Opmerkingen |
|---|---|---|---|
app.ister.server.TMDB.apikey | APP_ISTER_SERVER_TMDB_APIKEY | niet gezet | TMDB API read access token. Zonder deze wordt het ophalen van film-/seriemetadata overgeslagen — je krijgt kale bestandsnamen. |
app.ister.server.TMDB.max-requests-per-second | 30 | blijft onder TMDB's limiet van ~40 rps | |
app.ister.worker.tmdb.certification-country | US | ISO 3166-1-land waarvan de keuring/leeftijdsclassificatie (bv. 16, PG-13, TV-MA) bij films en shows wordt opgeslagen; valt terug op US en daarna op een willekeurig land dat er een heeft. | |
app.ister.languages | ISTER_LANGUAGES | en,nl | kommagescheiden ISO-639-1-tags; de eerste = primair. Bepaalt in welke talen metadata wordt opgehaald én welke talen de zoekindex krijgt. Wijzigen vereist een re-scan plus rebuildSearchIndex — zie Zoeken. |
app.ister.worker.musicbrainz.min-request-interval-millis | 1100 | tussenruimte tussen MusicBrainz-aanroepen; blijft net boven hun 1-verzoek-per-seconde-beleid — alleen verlagen tegen je eigen mirror | |
app.ister.worker.openlibrary.min-request-interval-millis | 1000 | tussenruimte tussen Open Library-aanroepen (zoeken, auteur- en werk-lookups) | |
app.ister.worker.wikipedia.min-request-interval-millis | 500 | tussenruimte tussen Wikidata-/Wikipedia-aanroepen (persoonsbio's, reeks-lookups) |
Zoeken (Typesense)
| Env var | Standaard |
|---|---|
TYPESENSE_ENABLED | false |
TYPESENSE_HOST / TYPESENSE_PORT / TYPESENSE_PROTOCOL | localhost / 8108 / http |
TYPESENSE_API_KEY / TYPESENSE_COLLECTION | leeg / media |
Zie Zoeken voor de procedure om in te schakelen en te herindexeren.
Transcoding
| Instelling | Env var | Standaard | Opmerkingen |
|---|---|---|---|
| FFmpeg-map | FFMPEG_DIR | /usr/bin | map met ffmpeg/ffprobe |
| mkvextract | MKVEXTRACT | /usr/bin/mkvextract | pakt dvd-ondertiteltracks (VobSub) uit voor de sprite-sheets van bitmap-ondertitels; blu-ray (PGS) heeft alleen FFmpeg nodig |
app.ister.transcoder.hls.hwaccel | HLS_HWACCEL | none | vaapi (Intel/AMD) of nvdec (NVIDIA); het compose-bestand toont de benodigde device-mappings |
app.ister.transcoder.hls.hwaccel-device | HLS_HWACCEL_DEVICE | /dev/dri/renderD128 | alleen VAAPI |
app.ister.transcoder.hls.max-concurrent-files | HLS_MAX_CONCURRENT_FILES | 2 | gelijktijdig getranscodeerde bestanden; pre-transcoding deelt dit budget |
Geavanceerde transcoding
Zelden aan te raken — de standaardwaarden passen bij de meeste opstellingen. Deze hebben geen eigen
korte env var (gebruik relaxed binding, bijv. APP_ISTER_TRANSCODER_HLS_MAX_BACKGROUND_FILES). De
mechaniek erachter staat in de architectuurgids, Transcoding.
| Property | Standaard | Opmerkingen |
|---|---|---|
app.ister.transcoder.hls.max-concurrent-passes | 4 | gelijktijdig lopende FFmpeg-passes (threadpoolgrootte) |
app.ister.transcoder.hls.max-background-files | 1 | bestanden die een achtergrond-pre-transcode mag vasthouden, onder het interactieve budget |
app.ister.transcoder.hls.max-background-passes | 2 | passes die een achtergrond-pre-transcode mag vasthouden |
BACKGROUND_NICE (app.ister.server.background-nice) | 10 | nice-waarde voor achtergrond-ffmpeg/ffprobe — achtergrondpasses en analyse (probing, crop- en introdetectie, ondertitelextractie) — zodat afspelen en uploads de CPU winnen; 0 = uit |
NICE_PATH (app.ister.server.nice-path) | /usr/bin/nice | pad naar de nice-binary voor bovenstaande |
app.ister.transcoder.hls.cache-retention-hours | 2 | een transcode-cachemap wordt pas verwijderd na zo lang onaangeraakt (en voorbij zijn keep-until) |
app.ister.transcoder.hls.segment-stability-ms | 200 | een segmentbestand moet zo lang ongewijzigd zijn voordat het als klaar telt |
app.ister.transcoder.hls.pass-timeout-multiplier | 4 | pass-timeout = mediaduur × dit |
app.ister.transcoder.hls.pass-timeout-min-seconds | 1800 | …maar nooit onder deze ondergrens |
app.ister.transcoder.hls.pass-stall-timeout-seconds | 60 | breek een pass af die zo lang geen nieuw segment schrijft |
app.ister.transcoder.hls.upload-drain-timeout-ms | 300000 | multi-node: hoe lang na afloop van een pass segmenten naar de vragende node geüpload blijven worden |
app.ister.server.hls.segment-timeout-ms | 60000 | hoe lang een HTTP-.ts-verzoek op dat segment van de encoder wacht |
app.ister.server.hls.master-playlist-timeout-ms | 120000 | hoe lang een master.m3u8-verzoek op het genereren van de playlists wacht |
Pre-transcoding en prefetch
Twee achtergrondmechanismen warmen de transcode-cache op zodat afspelen direct start. Pre-transcoding werkt vanuit de continue-watching-lijst; prefetch reageert op wat een play queue nú doet. Zie de architectuurgids, Transcoding.
| Property | Standaard | Opmerkingen |
|---|---|---|
app.ister.worker.pretranscode.enabled | true | runtime gecheckt: false stopt de 15-minuten-pre-transcode-planning volledig |
app.ister.server.pretranscode.keep-minutes | 30 | hoe lang een voor-getranscodeerd bestand warm blijft voordat het geveegd mag worden |
app.ister.server.prefetch.enabled | true | prefetch het volgende item in een play queue tijdens afspelen |
app.ister.server.prefetch.video-threshold-seconds | 120 | begin de volgende video te prefetchen na zoveel seconden in de huidige |
app.ister.server.prefetch.track-threshold-seconds | 60 | idem, voor audiotracks |
app.ister.server.prefetch.track-depth | 2 | hoeveel komende tracks vooruit te prefetchen |
app.ister.server.prefetch.keep-hours | 24 | hoe lang een geprefetcht bestand warm blijft |
Continue watching
| Env var | Standaard | Opmerkingen |
|---|---|---|
CONTINUE_WATCHING_HISTORY_DAYS | 150 | hoe ver de continue-watching-lijst terugkijkt; bepaalt ook wat pre-transcoding warm houdt |
CONTINUE_WATCHING_REBUILD_CRON | 0 30 3 * * * | nachtelijke zelfherstel-rebuild |
CONTINUE_WATCHING_REBUILD_ENABLED | true | runtime gecheckt: false slaat zowel de nachtelijke rebuild als de eenmalige startup-backfill over die een lege tabel vult |
Gebruik hier bij voorkeur de korte env vars in plaats van de lange property-namen: de
onderliggende properties zijn inconsistent gebonden (…rebuild.enabled met een punt, maar
…rebuild-cron met een streepje) — de env vars verbergen dat.
Cache-opschoning en podcasts
| Instelling | Standaard | Opmerkingen |
|---|---|---|
CACHE_CLEANUP_ENABLED / CACHE_CLEANUP_CRON | true / 0 30 4 * * * | dagelijkse zombie-sweep van cache- en tmp-mappen |
CACHE_CLEANUP_DRY_RUN | true | hij logt alleen totdat je dit op false zet — zie Onderhoud |
CACHE_CLEANUP_MIN_AGE | 24h | verwijdert nooit bestanden jonger dan dit |
app.ister.server.cache-cleanup.podcast-retention-days | 30 | gedownloade podcastafleveringen verlopen hierna, tenzij iemand middenin een aflevering zit |
app.ister.worker.podcast.auto-download-count | 3 | nieuwste afleveringen die per feed automatisch worden gedownload |
app.ister.worker.podcast.refresh-cron | 0 10 * * * * | feeds elk uur verversen |
app.ister.worker.podcast.refresh-min-interval-minutes | 30 | een feed wordt binnen dit venster niet opnieuw opgehaald, ook al vuurt de cron |
Media-upload
Zie Media uploaden voor waar deze tegen beschermen.
| Instelling | Standaard | Opmerkingen |
|---|---|---|
UPLOAD_ENABLED | true | zet de admin-upload-endpoints helemaal uit |
UPLOAD_CHUNK_SIZE | 16MB | één chunk-request; moet binnen de body-limiet van de reverse proxy passen, minimaal 5 MB |
UPLOAD_MAX_ACTIVE_SESSIONS / UPLOAD_MAX_FILES_PER_SESSION | 2 / 100000 | gelijktijdige uploads (clusterbreed), bestanden per upload (een Steam- of PS3-game is één upload van tot ~100k bestanden) |
UPLOAD_MAX_CONCURRENT_CHUNKS | 4 | chunk-requests die één node tegelijk afhandelt |
UPLOAD_SESSION_IDLE_TIMEOUT / UPLOAD_CLEANUP_INTERVAL | 24h / PT1H | wanneer een verlaten upload verloopt, en hoe vaak dat gecontroleerd wordt |
UPLOAD_MIN_FREE_SPACE | 5GB | ruimte die een lokale directory na een upload vrijhoudt |
Games
De per-gebruiker save-cloud van GAME-libraries (zie Libraries en media-indeling).
| Instelling | Standaard | Opmerkingen |
|---|---|---|
GAMES_SAVE_RETENTION | 10 | bewaarde save-snapshots per gebruiker per game; oudere worden verwijderd zodra een nieuwe binnenkomt |
GAMES_SAVE_MAX_BYTES | 512MB | grootste save-snapshot die een client mag uploaden |
GAMES_ACHIEVEMENT_ICON_MAX_BYTES | 512KB | grootste prestatie-icoon dat een client mag uploaden |
app.ister.worker.ludusavi.manifest-url | het Ludusavi-manifest op GitHub | bron van de save-locaties van pc-/Steam-games; gecachet in de cachemap onder ludusavi/, ververst elke refresh-hours (168); enabled: false zet de lookup uit |
Externe metadata-endpoints
Elke externe service die de server aanroept is een property met de echte service als standaard, dus normaal stel je hier niets van in. Ze bestaan zodat een deployment via een proxy of mock kan lopen — de CI van de chart wijst ze allemaal naar één WireMock-pod:
spring.cloud.openfeign.client.config.tmdb.url, app.ister.worker.tmdb.image-base,
app.ister.worker.musicbrainz.base / .coverart-release-base / .coverart-release-group-base /
.commons-filepath-base, app.ister.worker.openlibrary.base / .covers-base /
.author-photo-base, app.ister.worker.wikidata.entity-base / .api-base,
app.ister.worker.wikipedia.summary-template, app.ister.api.podcast.itunes-base,
app.ister.worker.ludusavi.manifest-url.
Libraries en directories
app.ister.disk.libraries[n].* en app.ister.disk.directories[n].* bepalen wat er gescand
wordt — volledig behandeld in Libraries en media-indeling.
Helper-nodes krijgen schijven van andere nodes toegewezen met app.ister.helper.disks[n].name
(+ .jobs), en een eigenaar geeft jobfamilies uit handen met app.ister.helper.offload-jobs — zie
Multi-node.
Health, metrics en overige interne knoppen
De Spring Actuator (/actuator/health, /actuator/metrics, /actuator/prometheus) draait op een
eigen poort, zodat die buiten de publieke API blijft. Die poortscheiding is de enige
bescherming — de actuator-endpoints zelf zijn niet-geauthenticeerd — dus publiceer of proxy poort
8081 nooit. Zie Installatie.
| Property | Standaard | Opmerkingen |
|---|---|---|
management.server.port | 8081 | poort voor de Actuator-endpoints |
management.endpoints.web.exposure.include | health,metrics,prometheus | welke Actuator-endpoints beschikbaar zijn |
app.ister.server.blur-hash.chunk-size | 500 | afbeeldingen per chunk tijdens de BlurHash-sweep (houdt een chunk onder de RabbitMQ-consumer-timeout) |
app.ister.server.segment-detect.chunk-size | 4 | afleveringen die per intro-/outro-detectiebericht worden gefingerprint; houd een chunk ruim onder de RabbitMQ-consumer-timeout |
SEGMENT_DETECT_CONCURRENCY (app.ister.server.segment-detect.concurrency) | 1 | intro-/outro-detectieconsumers op deze node; detectie van een seizoen wacht ook tot een upload naar zijn directory klaar is |
app.ister.server.crop-detect-backfill | true | ontsnappingsluik: false slaat de eenmalige crop-detectie-heranalyse van elk bestaand bestand bij de eerste scan na de upgrade over — zie Onderhoud |
app.ister.server.segment-detect-backfill | true | zelfde ontsnappingsluik voor het eenmalige intro-/outro-fingerprinten van elke bestaande aflevering |
Lokale overrides (ontwikkeling)
Draai je vanuit de broncode, dan gaan machinespecifieke instellingen in gegitignorede
*-local.yaml-bestanden naast het YAML-bestand van de module (bijv.
core/src/main/resources/core-local.yaml); ./gradlew bootRun activeert automatisch het
local-profiel. Containerdeployments gebruiken in plaats daarvan omgevingsvariabelen.