Decision. The arr apps as one umbrella Application
Alternative. One ArgoCD Application per app
Why. The pipeline is one operational unit: same node pin, same storage claim, deployed and upgraded together.
Watches for new TV episodes, grabs them, and hands them to the download stack
Sonarr tracks series, grabs episodes, and hands finished downloads to the library.
templates/sonarr/sonarr-rollout.yaml Sonarr Rollout
{{- $projectName := .Values.global.projectName -}}
{{- $imagePullSecretsName := .Values.global.imagePullSecretsName -}}
{{- $hostMediaMountPath := .Values.global.hostMediaMountPath -}}
{{- $configBasePath := .Values.global.configBasePath -}}
{{- $timeZone := .Values.global.timeZone -}}
{{- $userID := .Values.global.userID -}}
{{- with .Values.applications.sonarr }}
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: {{ .name }}
namespace: {{ $projectName }}
spec:
replicas: 1
strategy:
canary:
maxSurge: 0
maxUnavailable: 1
steps:
- setWeight: 100
selector:
matchLabels:
app: {{ .name }}
template:
metadata:
labels:
app: {{ .name }}
spec:
{{- include "media-systems.nodePlacement" $ | nindent 6 }}
serviceAccount: {{ $projectName }}-service-account
serviceAccountName: {{ $projectName}}-service-account
automountServiceAccountToken: true
containers:
- name: {{ .name }}
image: {{ .image }}
imagePullPolicy: IfNotPresent
ports:
- name: {{ .name | substr 0 9 }}-http
containerPort: {{ .ports.http }}
protocol: TCP
env:
- name: PGID
value: {{ $userID | quote }}
- name: PUID
value: {{ $userID | quote }}
- name: TZ
value: {{ $timeZone | quote }}
volumeMounts:
- name: {{ .name }}-config
mountPath: {{ .configMount }}
- name: {{ .name }}-series
mountPath: {{ .mediaMount }}/series
- name: {{ .name }}-anime
mountPath: {{ .mediaMount }}/anime
- name: {{ .name }}-downloads-series
mountPath: {{ .downloadMount }}/series
- name: {{ .name }}-downloads-anime
mountPath: {{ .downloadMount }}/anime
- name: {{ .name }}-media-cover
mountPath: /config/MediaCover
resources: {}
initContainers:
- name: {{ .name }}-configuration
image: busybox
command:
- "/bin/sh"
- "-c"
- |
echo "######## Mount config file #######";
mkdir -p {{ .configMount }};
cp /tmp/config.xml {{ .configMount }}/config.xml;
chown {{ $userID }}:{{ $userID }} {{ .configMount }}/config.xml;
chmod 400 {{ .configMount }}/config.xml;
chown -R {{ $userID }}:{{ $userID }} {{ .configMount }};
echo "Config Done";
volumeMounts:
- name: {{ .name }}-config
mountPath: {{ .configMount }}
- name: {{ .name }}-config-xml
mountPath: /tmp/config.xml
subPath: config.xml
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
volumes:
- name: {{ .name }}-series
hostPath:
path: {{ $hostMediaMountPath }}/series
type: Directory
- name: {{ .name }}-anime
hostPath:
path: {{ $hostMediaMountPath }}/anime
type: Directory
- name: {{ .name }}-downloads-series
hostPath:
path: {{ $hostMediaMountPath }}/downloads/series
type: Directory
- name: {{ .name }}-downloads-anime
hostPath:
path: {{ $hostMediaMountPath }}/downloads/anime
type: Directory
- name: {{ .name }}-config
emptyDir: {}
- name: {{ .name }}-config-xml
secret:
secretName: apps-configs-secret
items:
- key: sonarr_config
path: config.xml
- name: {{ .name }}-media-cover
hostPath:
path: {{ $configBasePath }}/{{ .name }}/MediaCover
type: DirectoryOrCreate
{{- end -}} templates/_shared-templates/config-tpl/sonarr-configs-config-tpl.yaml Config volume template: renders the Sonarr config directory
apiVersion: v1
kind: ConfigMap
metadata:
name: sonarr-configs-config-tpl
namespace: {{ .Release.Namespace }}
data:
sonarr_config: |
<Config>
<BindAddress>*</BindAddress>
<Port>8989</Port>
<SslPort>9898</SslPort>
<EnableSsl>False</EnableSsl>
<LaunchBrowser>True</LaunchBrowser>
<ApiKey>{{ `{{ .sonarr_api_key }}` }}</ApiKey>
<AuthenticationMethod>Forms</AuthenticationMethod>
<AuthenticationRequired>DisabledForLocalAddresses</AuthenticationRequired>
<Branch>main</Branch>
<LogLevel>debug</LogLevel>
<SslCertPath></SslCertPath>
<SslCertPassword></SslCertPassword>
<UrlBase></UrlBase>
<InstanceName>Sonarr</InstanceName>
<UpdateMechanism>Docker</UpdateMechanism>
<Theme>light</Theme>
<PostgresUser>{{ `{{ .db_username }}` }}</PostgresUser>
<PostgresPassword>{{ `{{ .db_password }}` }}</PostgresPassword>
<PostgresPort>{{ `{{ .db_port }}` }}</PostgresPort>
<PostgresHost>{{ `{{ .db_host_name }}` }}</PostgresHost>
<PostgresMainDb>{{ `{{ .sonarr_db_name }}` }}</PostgresMainDb>
<PostgresLogDb>{{ `{{ .sonarr_db_name }}` }}_logs</PostgresLogDb>
</Config> Decision. The arr apps as one umbrella Application
Alternative. One ArgoCD Application per app
Why. The pipeline is one operational unit: same node pin, same storage claim, deployed and upgraded together.