The chart bundles nine independently versioned upstreams, and eight of them were already pinned in values.yaml while only gluetun took its tag from appVersion. That split had no upside: it made gluetun the one image Renovate could not reach through the built-in helm-values manager, and it implied a "main app" the stack does not have. gluetun now carries gluetun.image.repository/tag like every other image, and the StatefulSet renders it from there. No tag comes from appVersion any more. Renovate picks all nine up through helm-values - the manager the repo already relies on for sidecar images - and ci/renovate-bump-chart.sh bumps the chart version with each update. Consequences, all documented where they bite: - renovate.json5 deliberately gets no app-version block for this chart. One would either duplicate the helm-values updates or rewrite an appVersion that selects no image. The absence is commented so it does not read as an oversight. - freesailarr leaves the change-app-version.yml choice list. That workflow rewrites appVersion and republishes, which for this chart would change no deployed image at all. - appVersion becomes a hand-maintained marker for the gluetun line. Since renovate-bump-chart.sh bumps the patch level on an unchanged appVersion, a gluetun update has to be paired with a hand edit of appVersion, or the +up suffix stops describing what the chart deploys. Noted in Chart.yaml, values.yaml and README.
713 lines
22 KiB
YAML
713 lines
22 KiB
YAML
# freesailarr runs gluetun plus the whole media automation stack in a single
|
|
# StatefulSet pod: every app container shares gluetun's network namespace, the
|
|
# containers talk to each other over localhost and all traffic leaves through
|
|
# the Wireguard tunnel.
|
|
#
|
|
# Image pinning (documented deviation from the Chart.AppVersion standard):
|
|
# NO image tag comes from appVersion. All nine images, gluetun included, are
|
|
# pinned here via <app>.image.repository / <app>.image.tag, because the stack
|
|
# combines nine independently versioned upstream projects and none of them is
|
|
# "the" one app version.
|
|
#
|
|
# That is also what puts every image under Renovate: the built-in helm-values
|
|
# manager reads image.repository/image.tag pairs out of this file and proposes
|
|
# one update per image, and ci/renovate-bump-chart.sh bumps the chart version
|
|
# along with it. A chart whose main image came from appVersion would instead
|
|
# need a hard-coded block in renovate.json5 - freesailarr deliberately has none.
|
|
#
|
|
# Chart.yaml's appVersion is therefore a hand-maintained marker for the gluetun
|
|
# line this chart is built around, not the source of any tag. Keep it in step
|
|
# with gluetun.image.tag below when you accept a gluetun update, otherwise the
|
|
# +up suffix of the chart version drifts away from what is actually deployed.
|
|
|
|
# Scale the whole chart down without uninstalling it: scaleDown: true renders
|
|
# every Deployment/StatefulSet with replicas: 0 (and suspends CronJobs) and
|
|
# takes precedence over any per-workload replicas value. PVCs, Secrets and
|
|
# Services stay in place; scaleDown: false brings the workloads back up.
|
|
scaleDown: false
|
|
|
|
# Replica count for the whole stack (one pod contains all containers); 0 is
|
|
# allowed and scales it down. The chart-global scaleDown flag takes precedence.
|
|
# More than 1 replica is not meaningful: every replica would run its own
|
|
# isolated stack on its own config volumes.
|
|
replicas: 1
|
|
|
|
secrets:
|
|
# op:// item path for the gluetun VPN credentials. The 1Password item must
|
|
# contain the fields "wireguard-private-key" (the Wireguard private key) and
|
|
# "wireguard-addresses" (the Wireguard interface address, e.g. 10.x.y.z/32).
|
|
gluetunSecretRef: null
|
|
|
|
# User/group the linuxserver.io containers drop to after init (their PUID/PGID
|
|
# mechanism) and the runAsUser/runAsGroup for the seerr and recyclarr
|
|
# containers. Media and config volumes must be writable for this user.
|
|
puid: 1000
|
|
pgid: 1000
|
|
# Timezone for all containers.
|
|
timezone: Europe/Zurich
|
|
|
|
securityContext:
|
|
# Pod-level security context. No pod-level runAsNonRoot/runAsUser: the pod
|
|
# mixes root containers (gluetun, linuxserver.io images) with non-root ones
|
|
# (seerr, recyclarr, flaresolverr); users are set per container instead.
|
|
# fsGroup (keep in sync with pgid) makes freshly provisioned config volumes
|
|
# group-writable for the non-root containers; fsGroupChangePolicy
|
|
# OnRootMismatch avoids recursively re-chowning the (large, shared) media
|
|
# claims on every pod start.
|
|
pod:
|
|
fsGroup: 1000
|
|
fsGroupChangePolicy: OnRootMismatch
|
|
|
|
storage:
|
|
# StorageClass for all config volumeClaimTemplates (null = cluster default).
|
|
storageClass: null
|
|
|
|
# Media libraries as pre-existing PVCs (shared with the separately deployed
|
|
# Jellyfin) - the chart mounts but never creates them. Each claim is required
|
|
# as soon as an app that mounts it is enabled:
|
|
# downloads: qbittorrent, radarr, sonarr
|
|
# movies: radarr, bazarr
|
|
# tv: sonarr, bazarr
|
|
#
|
|
# subPath mounts a sub-directory of the claim instead of its root (null = the
|
|
# claim root, i.e. one claim per category). The same existingClaim may back all
|
|
# three categories with different subPaths - one library volume, one
|
|
# sub-directory per category, e.g. downloads / movies / tv-shows.
|
|
#
|
|
# What this buys and what it does NOT buy - measured in a k3d cluster against
|
|
# this chart, because the usual argument for a shared volume is hardlinking:
|
|
# - It buys the layout: one claim to provision, back up and share with
|
|
# Jellyfin, with the categories as sibling directories instead of three
|
|
# separate volumes.
|
|
# - It does NOT buy hardlinked imports. Radarr and Sonarr import by moving,
|
|
# and a move within one filesystem can be a hardlink or a rename instead of
|
|
# a copy - but Kubernetes turns every volumeMount into its own bind mount,
|
|
# and link()/rename() across two mount points fails with EXDEV even when
|
|
# both sides are the same claim on the same device. Measured: /downloads and
|
|
# /movies in the radarr container both report device 65025 and resolve to
|
|
# the same PV directory, yet `ln /downloads/f /movies/f` fails with
|
|
# "Cross-device link", while the identical link succeeds when the claim root
|
|
# is mounted once and both categories are sub-directories under it.
|
|
# This is not a property of subPath: two plain mounts of the same claim
|
|
# without any subPath fail exactly the same way, so the chart has never
|
|
# supported cross-category hardlinks.
|
|
# - Consequence today: an import still copies, so download and library each
|
|
# hold a full copy until the torrent is removed.
|
|
# Getting hardlinks would mean giving the apps a single mount that contains all
|
|
# categories (the "one /data mount" layout the *arr guides recommend) instead of
|
|
# one mount per category - a separate change to the chart's mount layout, not a
|
|
# values setting.
|
|
media:
|
|
downloads:
|
|
existingClaim: null
|
|
subPath: null
|
|
movies:
|
|
existingClaim: null
|
|
subPath: null
|
|
tv:
|
|
existingClaim: null
|
|
subPath: null
|
|
|
|
# Ingress defaults. There is deliberately no global domain: every app carries
|
|
# its own <app>.ingress.host, so the hosts are independent of each other and
|
|
# may live in completely different domains. clusterIssuer, className and
|
|
# annotations are the defaults for all apps and can be overridden per app in
|
|
# the <app>.ingress block (an explicitly set per-app value always wins).
|
|
ingress:
|
|
# Master switch: false suppresses every app ingress regardless of the
|
|
# per-app toggles.
|
|
enabled: true
|
|
clusterIssuer: null
|
|
className: nginx
|
|
# Extra annotations for the Ingress objects; merged with the cert-manager
|
|
# cluster-issuer annotation the chart always sets.
|
|
annotations: {}
|
|
|
|
gluetun:
|
|
# Pinned here like every other image in this chart, so Renovate's helm-values
|
|
# manager proposes gluetun updates too. Docker Hub tags carry a v prefix.
|
|
image:
|
|
repository: qmcgaw/gluetun
|
|
tag: v3.41.1
|
|
vpn:
|
|
serviceProvider: mullvad
|
|
type: wireguard
|
|
serverCities: Zurich
|
|
serverCountries: Switzerland
|
|
dnsUpstreamResolvers: quad9
|
|
# Comma-separated CIDRs the gluetun firewall allows outbound traffic to
|
|
# outside the VPN tunnel. Set this to the cluster pod and service CIDRs
|
|
# (e.g. "10.42.0.0/16,10.43.0.0/16" on k3s) - without it the firewall
|
|
# blocks cluster-internal egress such as DNS lookups against cluster DNS
|
|
# and seerr talking to the in-cluster Jellyfin.
|
|
firewallOutboundSubnets: null
|
|
storage:
|
|
# Size of the gluetun config volume (server list cache under /gluetun).
|
|
size: 1Gi
|
|
# Extra environment variables, appended to the ones the chart always sets.
|
|
# Values are rendered through tpl; value, secretKeyRef and configMapKeyRef
|
|
# forms are supported. (Same for every <app>.env block below.)
|
|
env: []
|
|
# gluetun's built-in HTTP health server; the chart binds it to :9999 (env
|
|
# HEALTH_SERVER_ADDRESS) so the kubelet probes, which connect to the pod IP,
|
|
# can reach it. It returns 200 only while the VPN tunnel is up and working.
|
|
# Liveness is more tolerant (60s) than readiness (30s): during a short
|
|
# tunnel re-negotiation gluetun recovers on its own and a kubelet restart
|
|
# would only prolong the outage; the kill switch keeps all egress blocked
|
|
# the whole time, so nothing runs unprotected.
|
|
livenessProbe:
|
|
httpGet:
|
|
path: /
|
|
port: 9999
|
|
periodSeconds: 10
|
|
timeoutSeconds: 5
|
|
failureThreshold: 6
|
|
readinessProbe:
|
|
httpGet:
|
|
path: /
|
|
port: 9999
|
|
periodSeconds: 10
|
|
timeoutSeconds: 5
|
|
failureThreshold: 3
|
|
# The startup probe gates liveness/readiness. Budget for image start plus
|
|
# Wireguard handshake: 5s * 30 = 150s.
|
|
startupProbe:
|
|
httpGet:
|
|
path: /
|
|
port: 9999
|
|
periodSeconds: 5
|
|
timeoutSeconds: 5
|
|
failureThreshold: 30
|
|
resources:
|
|
# Limits are optional: memory and ephemeral-storage limits default to
|
|
# limitFactor x the request, an explicitly set limit always wins, and a
|
|
# CPU limit is only set when configured explicitly under "limits".
|
|
# (Same for every <app>.resources block below.)
|
|
limitFactor: 3
|
|
requests:
|
|
cpu: 0.1
|
|
memory: 128Mi
|
|
ephemeralStorage: 50Mi
|
|
# Deviations from the hardening baseline, forced by gluetun's role as VPN
|
|
# gateway:
|
|
# - runs as root (no runAsNonRoot): required to create the tun device and
|
|
# program the firewall.
|
|
# - NET_ADMIN capability: creates the Wireguard tunnel and the iptables
|
|
# rules (firewall, kill switch).
|
|
# - readOnlyRootFilesystem: false: gluetun rewrites /etc/resolv.conf and
|
|
# other files on its root filesystem at runtime.
|
|
securityContext:
|
|
allowPrivilegeEscalation: false
|
|
readOnlyRootFilesystem: false
|
|
capabilities:
|
|
drop:
|
|
- ALL
|
|
add:
|
|
- NET_ADMIN
|
|
|
|
qbittorrent:
|
|
enabled: true
|
|
image:
|
|
repository: linuxserver/qbittorrent
|
|
tag: 5.2.1
|
|
# Every app gets its own Ingress object (named <release>-<chart>-<app>-ingress)
|
|
# with its own TLS secret tls-<release>-<chart>-<app>-ingress, so the apps can
|
|
# be exposed independently and under unrelated hosts.
|
|
# host is required while enabled is true and has no default - an app whose
|
|
# ingress is switched off never demands one. clusterIssuer, className and
|
|
# annotations may be set here to override the global ingress block.
|
|
# (Same block for prowlarr, radarr, sonarr, seerr and bazarr below.)
|
|
ingress:
|
|
enabled: true
|
|
host: null
|
|
# clusterIssuer: null
|
|
# className: null
|
|
# annotations: {}
|
|
storage:
|
|
size: 1Gi
|
|
# Network interface qBittorrent binds its BitTorrent session to - gluetun's
|
|
# Wireguard device. Without this binding libtorrent listens and announces on
|
|
# every interface in the shared pod network namespace, including eth0 (the
|
|
# pod IP) and loopback. Those announces bypass the tunnel, so gluetun's kill
|
|
# switch (OUTPUT DROP except tun0 and the allowed cluster subnets) drops
|
|
# them: trackers report "skipping tracker announce (unreachable)", no peers
|
|
# are found and torrents stall at 0 bytes in stalledDL. Binding to tun0 is
|
|
# therefore both the functional fix and a leak fix - it stops qBittorrent
|
|
# from listening on the pod IP past the tunnel. The value is written into
|
|
# /config/qBittorrent/qBittorrent.conf by the config-interface init
|
|
# container below; setting it to null or "" removes that init container and
|
|
# leaves the binding to the user (not recommended).
|
|
networkInterface: tun0
|
|
# The init container that seeds qbittorrent.networkInterface into the
|
|
# persisted qBittorrent config before the app starts. Runs as puid/pgid so
|
|
# the config file keeps the ownership the app expects.
|
|
configInit:
|
|
# Auxiliary busybox image. Pinned independently of appVersion (which
|
|
# tracks gluetun); reviewed alongside every app-version update round.
|
|
image:
|
|
repository: busybox
|
|
tag: "1.38.0"
|
|
resources:
|
|
limitFactor: 3
|
|
requests:
|
|
cpu: 10m
|
|
memory: 16Mi
|
|
ephemeralStorage: 1Mi
|
|
securityContext:
|
|
runAsNonRoot: true
|
|
allowPrivilegeEscalation: false
|
|
readOnlyRootFilesystem: true
|
|
capabilities:
|
|
drop:
|
|
- ALL
|
|
env: []
|
|
livenessProbe:
|
|
httpGet:
|
|
path: /
|
|
port: 8080
|
|
periodSeconds: 10
|
|
timeoutSeconds: 5
|
|
failureThreshold: 3
|
|
readinessProbe:
|
|
httpGet:
|
|
path: /
|
|
port: 8080
|
|
periodSeconds: 10
|
|
timeoutSeconds: 5
|
|
failureThreshold: 3
|
|
# The startup probe gates liveness/readiness. Startup budget = 5s * 30 = 150s.
|
|
startupProbe:
|
|
httpGet:
|
|
path: /
|
|
port: 8080
|
|
periodSeconds: 5
|
|
timeoutSeconds: 5
|
|
failureThreshold: 30
|
|
resources:
|
|
limitFactor: 3
|
|
requests:
|
|
cpu: 0.2
|
|
memory: 512Mi
|
|
ephemeralStorage: 100Mi
|
|
# Deviations from the hardening baseline, forced by the linuxserver.io
|
|
# images (s6-overlay init that starts as root and drops to PUID/PGID):
|
|
# - no runAsNonRoot: s6-overlay must start as root to apply PUID/PGID and
|
|
# chown /config.
|
|
# - readOnlyRootFilesystem: false: the s6 init applies PUID/PGID by
|
|
# rewriting /etc/passwd and /etc/group and stages runtime state on the
|
|
# root filesystem. With a read-only root filesystem the containers still
|
|
# start, but silently keep the image's built-in uid/gid (911) instead of
|
|
# PUID/PGID (verified at runtime) - unacceptable for the shared media
|
|
# volumes.
|
|
# - capabilities: ALL dropped except what the s6-overlay init needs:
|
|
# CHOWN/FOWNER/DAC_OVERRIDE (taking ownership of /config and /run) and
|
|
# SETUID/SETGID (dropping from root to the PUID/PGID user).
|
|
# (Same block for all linuxserver.io containers: qbittorrent, prowlarr,
|
|
# radarr, sonarr, bazarr.)
|
|
securityContext:
|
|
allowPrivilegeEscalation: false
|
|
readOnlyRootFilesystem: false
|
|
capabilities:
|
|
drop:
|
|
- ALL
|
|
add:
|
|
- CHOWN
|
|
- DAC_OVERRIDE
|
|
- FOWNER
|
|
- SETGID
|
|
- SETUID
|
|
|
|
prowlarr:
|
|
enabled: true
|
|
image:
|
|
repository: linuxserver/prowlarr
|
|
tag: 2.3.5
|
|
# See the qbittorrent ingress comment.
|
|
ingress:
|
|
enabled: true
|
|
host: null
|
|
# clusterIssuer: null
|
|
# className: null
|
|
# annotations: {}
|
|
storage:
|
|
size: 1Gi
|
|
env: []
|
|
# The *arr apps expose /ping as an unauthenticated health endpoint.
|
|
livenessProbe:
|
|
httpGet:
|
|
path: /ping
|
|
port: 9696
|
|
periodSeconds: 10
|
|
timeoutSeconds: 5
|
|
failureThreshold: 3
|
|
readinessProbe:
|
|
httpGet:
|
|
path: /ping
|
|
port: 9696
|
|
periodSeconds: 10
|
|
timeoutSeconds: 5
|
|
failureThreshold: 3
|
|
# The startup probe gates liveness/readiness. Startup budget = 5s * 30 = 150s.
|
|
startupProbe:
|
|
httpGet:
|
|
path: /ping
|
|
port: 9696
|
|
periodSeconds: 5
|
|
timeoutSeconds: 5
|
|
failureThreshold: 30
|
|
resources:
|
|
limitFactor: 3
|
|
requests:
|
|
cpu: 0.1
|
|
memory: 256Mi
|
|
ephemeralStorage: 100Mi
|
|
# linuxserver.io image - see the qbittorrent securityContext comment.
|
|
securityContext:
|
|
allowPrivilegeEscalation: false
|
|
readOnlyRootFilesystem: false
|
|
capabilities:
|
|
drop:
|
|
- ALL
|
|
add:
|
|
- CHOWN
|
|
- DAC_OVERRIDE
|
|
- FOWNER
|
|
- SETGID
|
|
- SETUID
|
|
|
|
flaresolverr:
|
|
enabled: true
|
|
image:
|
|
repository: ghcr.io/flaresolverr/flaresolverr
|
|
tag: v3.5.0
|
|
# No ingress and no config volume: flaresolverr is stateless and only
|
|
# consumed by prowlarr over localhost.
|
|
env: []
|
|
# /health is flaresolverr's dedicated lightweight health endpoint.
|
|
livenessProbe:
|
|
httpGet:
|
|
path: /health
|
|
port: 8191
|
|
periodSeconds: 10
|
|
timeoutSeconds: 5
|
|
failureThreshold: 3
|
|
readinessProbe:
|
|
httpGet:
|
|
path: /health
|
|
port: 8191
|
|
periodSeconds: 10
|
|
timeoutSeconds: 5
|
|
failureThreshold: 3
|
|
# The startup probe gates liveness/readiness. Startup budget = 5s * 30 = 150s.
|
|
startupProbe:
|
|
httpGet:
|
|
path: /health
|
|
port: 8191
|
|
periodSeconds: 5
|
|
timeoutSeconds: 5
|
|
failureThreshold: 30
|
|
resources:
|
|
limitFactor: 3
|
|
requests:
|
|
cpu: 0.2
|
|
memory: 512Mi
|
|
ephemeralStorage: 200Mi
|
|
# Deviations from the hardening baseline, forced by the flaresolverr image:
|
|
# - readOnlyRootFilesystem: false: on startup flaresolverr copies and
|
|
# patches the chromedriver binary to the hardcoded path /app/chromedriver
|
|
# and writes chromedriver caches under /app (its home directory).
|
|
# - runAsUser/runAsGroup pin the image's "flaresolverr" user numerically
|
|
# (uid/gid 1000; the image declares it by name only, which the kubelet's
|
|
# runAsNonRoot check cannot verify).
|
|
# Chromium's scratch paths (/tmp, /dev/shm) are emptyDirs.
|
|
securityContext:
|
|
allowPrivilegeEscalation: false
|
|
readOnlyRootFilesystem: false
|
|
runAsNonRoot: true
|
|
runAsUser: 1000
|
|
runAsGroup: 1000
|
|
capabilities:
|
|
drop:
|
|
- ALL
|
|
|
|
radarr:
|
|
enabled: true
|
|
image:
|
|
repository: linuxserver/radarr
|
|
tag: 6.1.1
|
|
# See the qbittorrent ingress comment.
|
|
ingress:
|
|
enabled: true
|
|
host: null
|
|
# clusterIssuer: null
|
|
# className: null
|
|
# annotations: {}
|
|
storage:
|
|
size: 1Gi
|
|
env: []
|
|
livenessProbe:
|
|
httpGet:
|
|
path: /ping
|
|
port: 7878
|
|
periodSeconds: 10
|
|
timeoutSeconds: 5
|
|
failureThreshold: 3
|
|
readinessProbe:
|
|
httpGet:
|
|
path: /ping
|
|
port: 7878
|
|
periodSeconds: 10
|
|
timeoutSeconds: 5
|
|
failureThreshold: 3
|
|
# The startup probe gates liveness/readiness. Startup budget = 5s * 30 = 150s.
|
|
startupProbe:
|
|
httpGet:
|
|
path: /ping
|
|
port: 7878
|
|
periodSeconds: 5
|
|
timeoutSeconds: 5
|
|
failureThreshold: 30
|
|
resources:
|
|
limitFactor: 3
|
|
requests:
|
|
cpu: 0.1
|
|
memory: 256Mi
|
|
ephemeralStorage: 100Mi
|
|
# linuxserver.io image - see the qbittorrent securityContext comment.
|
|
securityContext:
|
|
allowPrivilegeEscalation: false
|
|
readOnlyRootFilesystem: false
|
|
capabilities:
|
|
drop:
|
|
- ALL
|
|
add:
|
|
- CHOWN
|
|
- DAC_OVERRIDE
|
|
- FOWNER
|
|
- SETGID
|
|
- SETUID
|
|
|
|
recyclarr:
|
|
enabled: true
|
|
image:
|
|
repository: ghcr.io/recyclarr/recyclarr
|
|
tag: 8.6.0
|
|
# No ingress: recyclarr has no web UI, it syncs TRaSH guides to radarr and
|
|
# sonarr on a schedule (daemon mode).
|
|
storage:
|
|
size: 1Gi
|
|
env: []
|
|
# recyclarr serves no HTTP port in daemon mode, so all probes exec the CLI.
|
|
livenessProbe:
|
|
exec:
|
|
command:
|
|
- recyclarr
|
|
- --version
|
|
periodSeconds: 30
|
|
timeoutSeconds: 10
|
|
failureThreshold: 3
|
|
readinessProbe:
|
|
exec:
|
|
command:
|
|
- recyclarr
|
|
- --version
|
|
periodSeconds: 30
|
|
timeoutSeconds: 10
|
|
failureThreshold: 3
|
|
# The startup probe gates liveness/readiness. Startup budget = 5s * 30 = 150s.
|
|
startupProbe:
|
|
exec:
|
|
command:
|
|
- recyclarr
|
|
- --version
|
|
periodSeconds: 5
|
|
timeoutSeconds: 10
|
|
failureThreshold: 30
|
|
resources:
|
|
limitFactor: 3
|
|
requests:
|
|
cpu: 0.05
|
|
memory: 128Mi
|
|
ephemeralStorage: 50Mi
|
|
# The image supports running as an arbitrary non-root user; runAsUser and
|
|
# runAsGroup are set from the global puid/pgid values in the template - do
|
|
# not set them here.
|
|
securityContext:
|
|
allowPrivilegeEscalation: false
|
|
readOnlyRootFilesystem: true
|
|
runAsNonRoot: true
|
|
capabilities:
|
|
drop:
|
|
- ALL
|
|
|
|
sonarr:
|
|
enabled: true
|
|
image:
|
|
repository: linuxserver/sonarr
|
|
tag: 4.0.17
|
|
# See the qbittorrent ingress comment.
|
|
ingress:
|
|
enabled: true
|
|
host: null
|
|
# clusterIssuer: null
|
|
# className: null
|
|
# annotations: {}
|
|
storage:
|
|
size: 1Gi
|
|
env: []
|
|
livenessProbe:
|
|
httpGet:
|
|
path: /ping
|
|
port: 8989
|
|
periodSeconds: 10
|
|
timeoutSeconds: 5
|
|
failureThreshold: 3
|
|
readinessProbe:
|
|
httpGet:
|
|
path: /ping
|
|
port: 8989
|
|
periodSeconds: 10
|
|
timeoutSeconds: 5
|
|
failureThreshold: 3
|
|
# The startup probe gates liveness/readiness. Startup budget = 5s * 30 = 150s.
|
|
startupProbe:
|
|
httpGet:
|
|
path: /ping
|
|
port: 8989
|
|
periodSeconds: 5
|
|
timeoutSeconds: 5
|
|
failureThreshold: 30
|
|
resources:
|
|
limitFactor: 3
|
|
requests:
|
|
cpu: 0.1
|
|
memory: 256Mi
|
|
ephemeralStorage: 100Mi
|
|
# linuxserver.io image - see the qbittorrent securityContext comment.
|
|
securityContext:
|
|
allowPrivilegeEscalation: false
|
|
readOnlyRootFilesystem: false
|
|
capabilities:
|
|
drop:
|
|
- ALL
|
|
add:
|
|
- CHOWN
|
|
- DAC_OVERRIDE
|
|
- FOWNER
|
|
- SETGID
|
|
- SETUID
|
|
|
|
seerr:
|
|
enabled: true
|
|
image:
|
|
repository: ghcr.io/seerr-team/seerr
|
|
tag: v3.3.0
|
|
# See the qbittorrent ingress comment.
|
|
ingress:
|
|
enabled: true
|
|
host: null
|
|
# clusterIssuer: null
|
|
# className: null
|
|
# annotations: {}
|
|
storage:
|
|
size: 1Gi
|
|
env: []
|
|
# /api/v1/settings/public answers unauthenticated once the app is up.
|
|
livenessProbe:
|
|
httpGet:
|
|
path: /api/v1/settings/public
|
|
port: 5055
|
|
periodSeconds: 10
|
|
timeoutSeconds: 5
|
|
failureThreshold: 3
|
|
readinessProbe:
|
|
httpGet:
|
|
path: /api/v1/settings/public
|
|
port: 5055
|
|
periodSeconds: 10
|
|
timeoutSeconds: 5
|
|
failureThreshold: 3
|
|
# The startup probe gates liveness/readiness. First boot runs database
|
|
# migrations: budget 10s * 30 = 300s.
|
|
startupProbe:
|
|
httpGet:
|
|
path: /api/v1/settings/public
|
|
port: 5055
|
|
periodSeconds: 10
|
|
timeoutSeconds: 5
|
|
failureThreshold: 30
|
|
resources:
|
|
limitFactor: 3
|
|
requests:
|
|
cpu: 0.1
|
|
memory: 256Mi
|
|
ephemeralStorage: 100Mi
|
|
# The image runs fine as an arbitrary non-root user; runAsUser and
|
|
# runAsGroup are set from the global puid/pgid values in the template - do
|
|
# not set them here.
|
|
securityContext:
|
|
allowPrivilegeEscalation: false
|
|
readOnlyRootFilesystem: true
|
|
runAsNonRoot: true
|
|
capabilities:
|
|
drop:
|
|
- ALL
|
|
|
|
bazarr:
|
|
enabled: true
|
|
image:
|
|
repository: linuxserver/bazarr
|
|
tag: 1.5.6
|
|
# See the qbittorrent ingress comment.
|
|
ingress:
|
|
enabled: true
|
|
host: null
|
|
# clusterIssuer: null
|
|
# className: null
|
|
# annotations: {}
|
|
storage:
|
|
size: 1Gi
|
|
env: []
|
|
# bazarr has no unauthenticated health endpoint; / serves the UI with 200.
|
|
livenessProbe:
|
|
httpGet:
|
|
path: /
|
|
port: 6767
|
|
periodSeconds: 10
|
|
timeoutSeconds: 5
|
|
failureThreshold: 3
|
|
readinessProbe:
|
|
httpGet:
|
|
path: /
|
|
port: 6767
|
|
periodSeconds: 10
|
|
timeoutSeconds: 5
|
|
failureThreshold: 3
|
|
# The startup probe gates liveness/readiness. Startup budget = 5s * 30 = 150s.
|
|
startupProbe:
|
|
httpGet:
|
|
path: /
|
|
port: 6767
|
|
periodSeconds: 5
|
|
timeoutSeconds: 5
|
|
failureThreshold: 30
|
|
resources:
|
|
limitFactor: 3
|
|
requests:
|
|
cpu: 0.1
|
|
memory: 256Mi
|
|
ephemeralStorage: 100Mi
|
|
# linuxserver.io image - see the qbittorrent securityContext comment.
|
|
securityContext:
|
|
allowPrivilegeEscalation: false
|
|
readOnlyRootFilesystem: false
|
|
capabilities:
|
|
drop:
|
|
- ALL
|
|
add:
|
|
- CHOWN
|
|
- DAC_OVERRIDE
|
|
- FOWNER
|
|
- SETGID
|
|
- SETUID
|