MediathekArr fakes a Usenet indexer towards Prowlarr and a SABnzbd downloader
towards Sonarr/Radarr and fetches from the ARD and ZDF media libraries. Both
consumers already share gluetun's network namespace, so they reach it over
127.0.0.1 - no service, no DNS, no ingress detour. Purely additive: the flag
defaults to false and a default render is byte-identical to 3.0.5 (verified
against the previous chart for both the default values and the CI values).
The four things that fail silently without them:
- A START GATE on gluetun. MediathekArr fetches its ruleset once at start and
never retries; started before the tunnel it answers every Newznab search with
0 results while the container is up, Ready and quiet. Kubernetes cannot order
two regular containers and an initContainer would deadlock, so the wait sits
in front of the image entrypoint: poll gluetun's health server on
127.0.0.1:9999 and exec the entrypoint afterwards; on timeout the container
exits rather than starting blind, because a crash loop is visible and an empty
indexer is not. The startup probe budget (300s) deliberately outlasts the gate
(180s).
- incomplete/ AND complete/ ON THE SHARED DOWNLOADS CLAIM, not in an emptyDir.
An emptyDir counts against the container's ephemeral-storage limit, and one
large download would have the kubelet evict the whole pod with all ten
containers - the trap ytdlp-web-player documents.
- THE COMPLETE PATH SONARR SEES. The claim is mounted at /downloads exactly as
sonarr/radarr mount it, and the chart sets DOWNLOAD_COMPLETE_PATH itself, so
the SABnzbd complete_dir it reports is the same absolute path on both sides.
- TWO PORTS: 5007 (SABnzbd role and UI, primary) and 5008 (Newznab role for
Prowlarr), both declared to gluetun's firewall and both on one Service. The
SABnzbd API is at /download/api - /api on 5007 answers with a misleading
Newznab validation error.
Further details:
- Image pinned by digest (tag + digest): "latest" is a 2024 build, "beta"
moves. Single-arch linux/amd64. The built-in helm-values manager cannot
follow that pair, so renovate.json5 gets the chart's first customManagers
block; verified by dry-run with two fixtures, since a matching and a broken
rule look identical while the pin is current.
- Hardened as measured: non-root, uid/gid from puid/pgid,
readOnlyRootFilesystem: true, all capabilities dropped, no PUID/PGID.
- Probes on measured 200 endpoints (there is no health endpoint): readiness and
startup on /download/, liveness as an exec covering BOTH ports, because one
container runs two processes and a wedged Newznab half is exactly what makes
searches come back empty.
- No ingress by default: the UI links its assets with root-absolute paths, so it
can only be served at the root of a host; on the shared domain that root
belongs to seerr. A sub-path fails the render instead of producing a broken
UI.
- values.yaml and NOTES.txt document the geo MARKER PROCEDURE (not a table of
series), the escape route of a German exit and its price for the whole stack,
the fail_message: null trap, and the HLS question as an open question.
- CI: mediathekarr enabled in ci/freesailarr/test-values.yaml, install timeout
raised to 1200s for the extra image and the gate.
Fixes#245
Only the newest Java line is maintained from now on. Publishing the chart once
per line out of one directory is what made the lines drift apart (#158): a
change reached whichever line happened to lie in the directory. java8 and java17
stay published as frozen artifacts at 4.0.0, java21 at 4.1.0, and none of them
gets another chart change.
Running an older JVM is now a decision at rollout time instead of a chart
version: image.tagOverride replaces the tag that otherwise comes from
appVersion. It is not called image.tag because it decouples the running image
from the chart version, and it is deliberately outside Renovate's reach -
renovate.json5 keeps tracking appVersion only.
The pairing of tag and minecraft.version is now checked at render time and fails
with both values named, the line each one belongs to, and where the tag came
from. Until now nothing checked it: a mismatch installed silently and only the
container failed afterwards. The boundaries are Mojang's, swept over all 102
releases of the piston-meta manifest (javaVersion.majorVersion): up to 1.16.5
Java 8, 1.17-1.17.1 Java 16, 1.18-1.20.4 Java 17, 1.20.5-1.21.11 Java 21, 26.1
and later Java 25. The 1.17 line was the one gap the chart's own notes did not
cover.
Two cases pass unchecked on purpose, documented in values.yaml and NOTES.txt: a
tag without a recognizable java<N> part, and a minecraft.version that is not a
plain numeric x[.y[.z]]. A guard that rejects what it does not understand gets
worked around instead of respected.
Major, because an installation that already runs a mismatched pair stops
rendering. It does not run today either - it now fails earlier and visibly.
game.seasonalEvents was handed to the container unchanged, into the image's
DISABLESEASONALEVENTS. Its default true therefore wrote
DISABLESEASONALEVENTS=true: the seasonal events were OFF in every install
this chart has ever produced, while values.schema.json described the very
same key as "true means events are enabled" (#215).
Of the two ways out, this is the loud one. Inverting the template under the
old key would have flipped the behaviour of every existing release in
silence - the same class of mistake that created the issue. Renaming the key
cannot be missed: game.seasonalEvents no longer exists, additionalProperties
is false on the game block, and a values file that still carries it fails
schema validation on upgrade instead of quietly meaning the opposite.
The new key is positive (enableSeasonalEvents) to avoid a double negative,
so the chart negates it on the way into the env var. Go's "not" cannot do
that: it reads every non-empty string as true, and the schema deliberately
accepts the string form of booleans, so "false" would have flipped the wrong
way. The helper compares explicitly and fails on anything that is neither
true nor false rather than filing it under "off".
The default is enableSeasonalEvents: false, which renders the
DISABLESEASONALEVENTS this chart has always rendered. At chart defaults the
6.1.0 and 7.0.0 manifests are identical, so upgrading alone moves no server;
switching the events on is now a deliberate act with a key that means it.
Separate finding from the same issue, fixed here because it lives in the
block being touched: "--set game=null" - or a leftover "game:" whose
sub-keys were deleted - aborted the render with a nil pointer at
.Values.game.maxPlayers. The game block never got the null-safe treatment of
#99 that probes, security contexts and resources have. It now falls back to
the documented defaults, and the schema accepts the null accordingly. The
same gap remains in the dev and server blocks; it is reported, not fixed
here.
Major bump: a values key is removed, and the schema rejects it.
The chart told operators that adding a duplicate env name to an installed
release makes the next upgrade fail in the API server, quoting "The order in
patch list ... doesn't match $setElementOrder list". Measured against helm
3.19.0 and Kubernetes 1.35, it does not fail: the upgrade succeeds, helm prints
"Release has been upgraded", and Kubernetes merges the env list by name, so the
duplicate pair collapses to the chart's own entry and the operator's override is
discarded without a word. At install time the same values behave differently -
both entries reach the pod, the later one wins, and the API server says so with
"hides previous definition of ..., which may be dropped when using apply".
The advice that followed from the old claim survives - such a switch only takes
at install time - but the stated reason was wrong in the dangerous direction. A
reader who expects a loud failure treats a green upgrade as proof the override
took effect, and green is exactly what a silently dropped override looks like.
The text now names the real failure mode and tells the reader to read the value
back off the Deployment. README carries the same correction, because every chart
in this repo offers the same additive env block.
Also records what the earlier measurement left open. With the database scaled
back up the pod returns to Ready on its own after about five seconds, restart
count still 0, so leaving the liveness group untouched costs no manual recovery.
And the limit of that signal belongs next to it: the db indicator validates a
connection, not the schema, so a database that came back empty still put the pod
back to Ready with /actuator/health at 200.
MANAGEMENT_ENDPOINT_HEALTH_GROUP_READINESS_INCLUDE=readinessState,db puts the datasource into Spring Boot's readiness group, which shipped with readinessState alone: a total database outage left the pod 1/1 Ready while every request failed. Naming the members replaces the default, so readinessState is repeated. The liveness group stays untouched on purpose, because an outage has to keep traffic away rather than add a crash loop to it.
MANAGEMENT_HEALTH_MAIL_ENABLED=false removes the mail indicator, which pinned the aggregate /actuator/health at 503 for the whole life of a healthy release, because the chart's mail wiring points at localhost:1025 where nothing listens. values.yaml and NOTES.txt document what that costs and when it has to be switched back on.