arrstack: set *arr UrlBase=/<app> for path-based proxy hosting (#378)
## Why arrproxy forwards `arrstack.unkin.net/<app>/...` to each *arr Service **preserving** the `/<app>` prefix. Without a matching `<UrlBase>` the apps 307-redirect to `/`, breaking path-based hosting. Prerequisite for arrproxy path routing (PR #377... arrproxy service account added in #376). ## Change Extend the existing idempotent `apikey-init` init container in sonarr/radarr/prowlarr to also enforce `<UrlBase>/<app></UrlBase>` in `/config/config.xml` (sonarr=/sonarr, radarr=/radarr, prowlarr=/prowlarr): - Set/replace `<UrlBase>` if present, insert after `<Config>` if absent, or write both `<ApiKey>` + `<UrlBase>` when creating a fresh config. `<ApiKey>` handling is unchanged. - Because Servarr moves all routes (including `/ping`) under the URL base, update liveness/readiness probes from `/ping` to `/<app>/ping` so they don't 404 once UrlBase is set. nzbget is not fronted by arrproxy and is left untouched. ## Validation - `kustomize build --enable-helm apps/overlays/au-syd1/arrstack` succeeds - `pre-commit` (yamllint etc.) passes --------- Co-authored-by: BenVincent <benvin@main.unkin.net> Co-authored-by: unkin-agent <unkin-agent@git.unkin.net> Reviewed-on: #378 Co-authored-by: Unkin Agent <unkin-agent@unkin.net> Co-committed-by: Unkin Agent <unkin-agent@unkin.net>
This commit was merged in pull request #378.
This commit is contained in:
@@ -21,10 +21,12 @@ spec:
|
|||||||
fsGroup: 1000
|
fsGroup: 1000
|
||||||
fsGroupChangePolicy: OnRootMismatch
|
fsGroupChangePolicy: OnRootMismatch
|
||||||
initContainers:
|
initContainers:
|
||||||
# Enforce the Vault-sourced API key in /config/config.xml before the app
|
# Enforce the Vault-sourced API key and the reverse-proxy URL base in
|
||||||
# starts. Vault is source of truth (override bootstrap): the key is minted
|
# /config/config.xml before the app starts. Vault is source of truth
|
||||||
# in Vault, synced by VSO into the prowlarr-apikey Secret, and written here.
|
# (override bootstrap): the key is minted in Vault, synced by VSO into the
|
||||||
# Runs as root to fix ownership; touches only the <ApiKey> element.
|
# prowlarr-apikey Secret, and written here. UrlBase=/prowlarr lets arrproxy
|
||||||
|
# forward arrstack.unkin.net/prowlarr/... with the prefix preserved (no 307).
|
||||||
|
# Runs as root to fix ownership; touches only <ApiKey> and <UrlBase>.
|
||||||
- name: apikey-init
|
- name: apikey-init
|
||||||
image: artifactapi.k8s.syd1.au.unkin.net/dockerhub/library/busybox:1.37.0
|
image: artifactapi.k8s.syd1.au.unkin.net/dockerhub/library/busybox:1.37.0
|
||||||
imagePullPolicy: IfNotPresent
|
imagePullPolicy: IfNotPresent
|
||||||
@@ -43,21 +45,29 @@ spec:
|
|||||||
set -eu
|
set -eu
|
||||||
case "$API_KEY" in
|
case "$API_KEY" in
|
||||||
"" | *[!0-9a-fA-F]*)
|
"" | *[!0-9a-fA-F]*)
|
||||||
echo "apikey-init: API_KEY missing or not hex; refusing" >&2
|
echo "config-init: API_KEY missing or not hex; refusing" >&2
|
||||||
exit 1
|
exit 1
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
URL_BASE=/prowlarr
|
||||||
CFG=/config/config.xml
|
CFG=/config/config.xml
|
||||||
if [ ! -f "$CFG" ]; then
|
if [ ! -f "$CFG" ]; then
|
||||||
printf '<Config>\n <ApiKey>%s</ApiKey>\n</Config>\n' "$API_KEY" > "$CFG"
|
printf '<Config>\n <ApiKey>%s</ApiKey>\n <UrlBase>%s</UrlBase>\n</Config>\n' "$API_KEY" "$URL_BASE" > "$CFG"
|
||||||
elif grep -q '<ApiKey>' "$CFG"; then
|
else
|
||||||
|
if grep -q '<ApiKey>' "$CFG"; then
|
||||||
sed -i "s|<ApiKey>[^<]*</ApiKey>|<ApiKey>${API_KEY}</ApiKey>|" "$CFG"
|
sed -i "s|<ApiKey>[^<]*</ApiKey>|<ApiKey>${API_KEY}</ApiKey>|" "$CFG"
|
||||||
else
|
else
|
||||||
sed -i "s|<Config>|<Config>\n <ApiKey>${API_KEY}</ApiKey>|" "$CFG"
|
sed -i "s|<Config>|<Config>\n <ApiKey>${API_KEY}</ApiKey>|" "$CFG"
|
||||||
fi
|
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
|
||||||
|
fi
|
||||||
chown 1000:1000 "$CFG"
|
chown 1000:1000 "$CFG"
|
||||||
chmod 600 "$CFG"
|
chmod 600 "$CFG"
|
||||||
echo "apikey-init: <ApiKey> enforced from Vault"
|
echo "config-init: <ApiKey> and <UrlBase>=${URL_BASE} enforced from Vault"
|
||||||
resources:
|
resources:
|
||||||
requests:
|
requests:
|
||||||
cpu: 50m
|
cpu: 50m
|
||||||
@@ -85,7 +95,7 @@ spec:
|
|||||||
value: Australia/Sydney
|
value: Australia/Sydney
|
||||||
livenessProbe:
|
livenessProbe:
|
||||||
httpGet:
|
httpGet:
|
||||||
path: /ping
|
path: /prowlarr/ping
|
||||||
port: http
|
port: http
|
||||||
initialDelaySeconds: 30
|
initialDelaySeconds: 30
|
||||||
periodSeconds: 30
|
periodSeconds: 30
|
||||||
@@ -93,7 +103,7 @@ spec:
|
|||||||
failureThreshold: 3
|
failureThreshold: 3
|
||||||
readinessProbe:
|
readinessProbe:
|
||||||
httpGet:
|
httpGet:
|
||||||
path: /ping
|
path: /prowlarr/ping
|
||||||
port: http
|
port: http
|
||||||
initialDelaySeconds: 10
|
initialDelaySeconds: 10
|
||||||
periodSeconds: 10
|
periodSeconds: 10
|
||||||
|
|||||||
@@ -21,10 +21,12 @@ spec:
|
|||||||
fsGroup: 1000
|
fsGroup: 1000
|
||||||
fsGroupChangePolicy: OnRootMismatch
|
fsGroupChangePolicy: OnRootMismatch
|
||||||
initContainers:
|
initContainers:
|
||||||
# Enforce the Vault-sourced API key in /config/config.xml before the app
|
# Enforce the Vault-sourced API key and the reverse-proxy URL base in
|
||||||
# starts. Vault is source of truth (override bootstrap): the key is minted
|
# /config/config.xml before the app starts. Vault is source of truth
|
||||||
# in Vault, synced by VSO into the radarr-apikey Secret, and written here.
|
# (override bootstrap): the key is minted in Vault, synced by VSO into the
|
||||||
# Runs as root to fix ownership; touches only the <ApiKey> element.
|
# 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> and <UrlBase>.
|
||||||
- name: apikey-init
|
- name: apikey-init
|
||||||
image: artifactapi.k8s.syd1.au.unkin.net/dockerhub/library/busybox:1.37.0
|
image: artifactapi.k8s.syd1.au.unkin.net/dockerhub/library/busybox:1.37.0
|
||||||
imagePullPolicy: IfNotPresent
|
imagePullPolicy: IfNotPresent
|
||||||
@@ -43,21 +45,29 @@ spec:
|
|||||||
set -eu
|
set -eu
|
||||||
case "$API_KEY" in
|
case "$API_KEY" in
|
||||||
"" | *[!0-9a-fA-F]*)
|
"" | *[!0-9a-fA-F]*)
|
||||||
echo "apikey-init: API_KEY missing or not hex; refusing" >&2
|
echo "config-init: API_KEY missing or not hex; refusing" >&2
|
||||||
exit 1
|
exit 1
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
URL_BASE=/radarr
|
||||||
CFG=/config/config.xml
|
CFG=/config/config.xml
|
||||||
if [ ! -f "$CFG" ]; then
|
if [ ! -f "$CFG" ]; then
|
||||||
printf '<Config>\n <ApiKey>%s</ApiKey>\n</Config>\n' "$API_KEY" > "$CFG"
|
printf '<Config>\n <ApiKey>%s</ApiKey>\n <UrlBase>%s</UrlBase>\n</Config>\n' "$API_KEY" "$URL_BASE" > "$CFG"
|
||||||
elif grep -q '<ApiKey>' "$CFG"; then
|
else
|
||||||
|
if grep -q '<ApiKey>' "$CFG"; then
|
||||||
sed -i "s|<ApiKey>[^<]*</ApiKey>|<ApiKey>${API_KEY}</ApiKey>|" "$CFG"
|
sed -i "s|<ApiKey>[^<]*</ApiKey>|<ApiKey>${API_KEY}</ApiKey>|" "$CFG"
|
||||||
else
|
else
|
||||||
sed -i "s|<Config>|<Config>\n <ApiKey>${API_KEY}</ApiKey>|" "$CFG"
|
sed -i "s|<Config>|<Config>\n <ApiKey>${API_KEY}</ApiKey>|" "$CFG"
|
||||||
fi
|
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
|
||||||
|
fi
|
||||||
chown 1000:1000 "$CFG"
|
chown 1000:1000 "$CFG"
|
||||||
chmod 600 "$CFG"
|
chmod 600 "$CFG"
|
||||||
echo "apikey-init: <ApiKey> enforced from Vault"
|
echo "config-init: <ApiKey> and <UrlBase>=${URL_BASE} enforced from Vault"
|
||||||
resources:
|
resources:
|
||||||
requests:
|
requests:
|
||||||
cpu: 50m
|
cpu: 50m
|
||||||
@@ -85,7 +95,7 @@ spec:
|
|||||||
value: Australia/Sydney
|
value: Australia/Sydney
|
||||||
livenessProbe:
|
livenessProbe:
|
||||||
httpGet:
|
httpGet:
|
||||||
path: /ping
|
path: /radarr/ping
|
||||||
port: http
|
port: http
|
||||||
initialDelaySeconds: 30
|
initialDelaySeconds: 30
|
||||||
periodSeconds: 30
|
periodSeconds: 30
|
||||||
@@ -93,7 +103,7 @@ spec:
|
|||||||
failureThreshold: 3
|
failureThreshold: 3
|
||||||
readinessProbe:
|
readinessProbe:
|
||||||
httpGet:
|
httpGet:
|
||||||
path: /ping
|
path: /radarr/ping
|
||||||
port: http
|
port: http
|
||||||
initialDelaySeconds: 10
|
initialDelaySeconds: 10
|
||||||
periodSeconds: 10
|
periodSeconds: 10
|
||||||
|
|||||||
@@ -24,10 +24,12 @@ spec:
|
|||||||
fsGroup: 1000
|
fsGroup: 1000
|
||||||
fsGroupChangePolicy: OnRootMismatch
|
fsGroupChangePolicy: OnRootMismatch
|
||||||
initContainers:
|
initContainers:
|
||||||
# Enforce the Vault-sourced API key in /config/config.xml before the app
|
# Enforce the Vault-sourced API key and the reverse-proxy URL base in
|
||||||
# starts. Vault is source of truth (override bootstrap): the key is minted
|
# /config/config.xml before the app starts. Vault is source of truth
|
||||||
# in Vault, synced by VSO into the sonarr-apikey Secret, and written here.
|
# (override bootstrap): the key is minted in Vault, synced by VSO into the
|
||||||
# Runs as root to fix ownership; touches only the <ApiKey> element.
|
# sonarr-apikey Secret, and written here. UrlBase=/sonarr lets arrproxy
|
||||||
|
# forward arrstack.unkin.net/sonarr/... with the prefix preserved (no 307).
|
||||||
|
# Runs as root to fix ownership; touches only <ApiKey> and <UrlBase>.
|
||||||
- name: apikey-init
|
- name: apikey-init
|
||||||
image: artifactapi.k8s.syd1.au.unkin.net/dockerhub/library/busybox:1.37.0
|
image: artifactapi.k8s.syd1.au.unkin.net/dockerhub/library/busybox:1.37.0
|
||||||
imagePullPolicy: IfNotPresent
|
imagePullPolicy: IfNotPresent
|
||||||
@@ -46,21 +48,29 @@ spec:
|
|||||||
set -eu
|
set -eu
|
||||||
case "$API_KEY" in
|
case "$API_KEY" in
|
||||||
"" | *[!0-9a-fA-F]*)
|
"" | *[!0-9a-fA-F]*)
|
||||||
echo "apikey-init: API_KEY missing or not hex; refusing" >&2
|
echo "config-init: API_KEY missing or not hex; refusing" >&2
|
||||||
exit 1
|
exit 1
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
URL_BASE=/sonarr
|
||||||
CFG=/config/config.xml
|
CFG=/config/config.xml
|
||||||
if [ ! -f "$CFG" ]; then
|
if [ ! -f "$CFG" ]; then
|
||||||
printf '<Config>\n <ApiKey>%s</ApiKey>\n</Config>\n' "$API_KEY" > "$CFG"
|
printf '<Config>\n <ApiKey>%s</ApiKey>\n <UrlBase>%s</UrlBase>\n</Config>\n' "$API_KEY" "$URL_BASE" > "$CFG"
|
||||||
elif grep -q '<ApiKey>' "$CFG"; then
|
else
|
||||||
|
if grep -q '<ApiKey>' "$CFG"; then
|
||||||
sed -i "s|<ApiKey>[^<]*</ApiKey>|<ApiKey>${API_KEY}</ApiKey>|" "$CFG"
|
sed -i "s|<ApiKey>[^<]*</ApiKey>|<ApiKey>${API_KEY}</ApiKey>|" "$CFG"
|
||||||
else
|
else
|
||||||
sed -i "s|<Config>|<Config>\n <ApiKey>${API_KEY}</ApiKey>|" "$CFG"
|
sed -i "s|<Config>|<Config>\n <ApiKey>${API_KEY}</ApiKey>|" "$CFG"
|
||||||
fi
|
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
|
||||||
|
fi
|
||||||
chown 1000:1000 "$CFG"
|
chown 1000:1000 "$CFG"
|
||||||
chmod 600 "$CFG"
|
chmod 600 "$CFG"
|
||||||
echo "apikey-init: <ApiKey> enforced from Vault"
|
echo "config-init: <ApiKey> and <UrlBase>=${URL_BASE} enforced from Vault"
|
||||||
resources:
|
resources:
|
||||||
requests:
|
requests:
|
||||||
cpu: 50m
|
cpu: 50m
|
||||||
@@ -88,7 +98,7 @@ spec:
|
|||||||
value: Australia/Sydney
|
value: Australia/Sydney
|
||||||
livenessProbe:
|
livenessProbe:
|
||||||
httpGet:
|
httpGet:
|
||||||
path: /ping
|
path: /sonarr/ping
|
||||||
port: http
|
port: http
|
||||||
initialDelaySeconds: 30
|
initialDelaySeconds: 30
|
||||||
periodSeconds: 30
|
periodSeconds: 30
|
||||||
@@ -96,7 +106,7 @@ spec:
|
|||||||
failureThreshold: 3
|
failureThreshold: 3
|
||||||
readinessProbe:
|
readinessProbe:
|
||||||
httpGet:
|
httpGet:
|
||||||
path: /ping
|
path: /sonarr/ping
|
||||||
port: http
|
port: http
|
||||||
initialDelaySeconds: 10
|
initialDelaySeconds: 10
|
||||||
periodSeconds: 10
|
periodSeconds: 10
|
||||||
|
|||||||
Reference in New Issue
Block a user