66eb81b5e0
The *arr UIs behind arrproxy prompt "Authentication Required" because Sonarr v4 refuses remote access when AuthenticationMethod=None. Since arrproxy + oauth2-proxy already authenticate every user at the front door, the *arr apps should defer UI auth to the proxy instead of double-prompting. Extend the existing apikey-init container for sonarr/radarr/prowlarr to also idempotently enforce <AuthenticationMethod>External</AuthenticationMethod> and <AuthenticationRequired>Enabled</AuthenticationRequired> in /config/config.xml (create or replace, without disturbing ApiKey/UrlBase). In Servarr v4 External registers the same NoAuthenticationHandler as None (no username header required) but is exempt from the None remote-access block, so it stops the UI login prompt without needing arrproxy to forward any identity header (arrproxy's trustBoundary strips those by design).
146 lines
5.4 KiB
YAML
146 lines
5.4 KiB
YAML
---
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: radarr
|
|
namespace: arrstack
|
|
spec:
|
|
replicas: 1
|
|
strategy:
|
|
# RWO config PVC + single stateful SQLite DB: never run two pods at once.
|
|
type: Recreate
|
|
selector:
|
|
matchLabels:
|
|
app: radarr
|
|
template:
|
|
metadata:
|
|
labels:
|
|
app: radarr
|
|
spec:
|
|
securityContext:
|
|
fsGroup: 1000
|
|
fsGroupChangePolicy: OnRootMismatch
|
|
initContainers:
|
|
# Enforce the Vault-sourced API key and the reverse-proxy URL base in
|
|
# /config/config.xml before the app starts. Vault is source of truth
|
|
# (override bootstrap): the key is minted in Vault, synced by VSO into the
|
|
# radarr-apikey Secret, and written here. UrlBase=/radarr lets arrproxy
|
|
# forward arrstack.unkin.net/radarr/... with the prefix preserved (no 307).
|
|
# Runs as root to fix ownership; touches only <ApiKey>, <UrlBase>, and
|
|
# <AuthenticationMethod>=External + <AuthenticationRequired>. External makes
|
|
# the *arr defer UI login to arrproxy/oauth2-proxy (same no-auth request
|
|
# handler as None, but permits remote access without prompting).
|
|
- name: apikey-init
|
|
image: artifactapi.k8s.syd1.au.unkin.net/dockerhub/library/busybox:1.37.0
|
|
imagePullPolicy: IfNotPresent
|
|
securityContext:
|
|
runAsUser: 0
|
|
env:
|
|
- name: API_KEY
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: radarr-apikey
|
|
key: apitoken
|
|
command:
|
|
- sh
|
|
- -c
|
|
- |
|
|
set -eu
|
|
case "$API_KEY" in
|
|
"" | *[!0-9a-fA-F]*)
|
|
echo "config-init: API_KEY missing or not hex; refusing" >&2
|
|
exit 1
|
|
;;
|
|
esac
|
|
URL_BASE=/radarr
|
|
AUTH_METHOD=External
|
|
AUTH_REQUIRED=Enabled
|
|
CFG=/config/config.xml
|
|
if [ ! -f "$CFG" ]; then
|
|
printf '<Config>\n <ApiKey>%s</ApiKey>\n <UrlBase>%s</UrlBase>\n <AuthenticationMethod>%s</AuthenticationMethod>\n <AuthenticationRequired>%s</AuthenticationRequired>\n</Config>\n' "$API_KEY" "$URL_BASE" "$AUTH_METHOD" "$AUTH_REQUIRED" > "$CFG"
|
|
else
|
|
if grep -q '<ApiKey>' "$CFG"; then
|
|
sed -i "s|<ApiKey>[^<]*</ApiKey>|<ApiKey>${API_KEY}</ApiKey>|" "$CFG"
|
|
else
|
|
sed -i "s|<Config>|<Config>\n <ApiKey>${API_KEY}</ApiKey>|" "$CFG"
|
|
fi
|
|
if grep -q '<UrlBase>' "$CFG"; then
|
|
sed -i "s|<UrlBase>[^<]*</UrlBase>|<UrlBase>${URL_BASE}</UrlBase>|" "$CFG"
|
|
else
|
|
sed -i "s|<Config>|<Config>\n <UrlBase>${URL_BASE}</UrlBase>|" "$CFG"
|
|
fi
|
|
if grep -q '<AuthenticationMethod>' "$CFG"; then
|
|
sed -i "s|<AuthenticationMethod>[^<]*</AuthenticationMethod>|<AuthenticationMethod>${AUTH_METHOD}</AuthenticationMethod>|" "$CFG"
|
|
else
|
|
sed -i "s|<Config>|<Config>\n <AuthenticationMethod>${AUTH_METHOD}</AuthenticationMethod>|" "$CFG"
|
|
fi
|
|
if grep -q '<AuthenticationRequired>' "$CFG"; then
|
|
sed -i "s|<AuthenticationRequired>[^<]*</AuthenticationRequired>|<AuthenticationRequired>${AUTH_REQUIRED}</AuthenticationRequired>|" "$CFG"
|
|
else
|
|
sed -i "s|<Config>|<Config>\n <AuthenticationRequired>${AUTH_REQUIRED}</AuthenticationRequired>|" "$CFG"
|
|
fi
|
|
fi
|
|
chown 1000:1000 "$CFG"
|
|
chmod 600 "$CFG"
|
|
echo "config-init: <ApiKey>, <UrlBase>=${URL_BASE}, <AuthenticationMethod>=${AUTH_METHOD}, <AuthenticationRequired>=${AUTH_REQUIRED} enforced from Vault"
|
|
resources:
|
|
requests:
|
|
cpu: 50m
|
|
memory: 32Mi
|
|
limits:
|
|
cpu: 200m
|
|
memory: 64Mi
|
|
volumeMounts:
|
|
- name: config
|
|
mountPath: /config
|
|
containers:
|
|
- name: radarr
|
|
image: artifactapi.k8s.syd1.au.unkin.net/dockerhub/linuxserver/radarr:6.3.0
|
|
imagePullPolicy: IfNotPresent
|
|
ports:
|
|
- name: http
|
|
containerPort: 7878
|
|
protocol: TCP
|
|
env:
|
|
- name: PUID
|
|
value: "1000"
|
|
- name: PGID
|
|
value: "1000"
|
|
- name: TZ
|
|
value: Australia/Sydney
|
|
livenessProbe:
|
|
httpGet:
|
|
path: /radarr/ping
|
|
port: http
|
|
initialDelaySeconds: 30
|
|
periodSeconds: 30
|
|
timeoutSeconds: 5
|
|
failureThreshold: 3
|
|
readinessProbe:
|
|
httpGet:
|
|
path: /radarr/ping
|
|
port: http
|
|
initialDelaySeconds: 10
|
|
periodSeconds: 10
|
|
timeoutSeconds: 5
|
|
failureThreshold: 3
|
|
resources:
|
|
requests:
|
|
cpu: 100m
|
|
memory: 256Mi
|
|
limits:
|
|
cpu: "1"
|
|
memory: 1Gi
|
|
volumeMounts:
|
|
- name: config
|
|
mountPath: /config
|
|
- name: media-movies
|
|
mountPath: /media/movies
|
|
volumes:
|
|
- name: config
|
|
persistentVolumeClaim:
|
|
claimName: radarr-config
|
|
- name: media-movies
|
|
persistentVolumeClaim:
|
|
claimName: media-movies
|