diff --git a/kube/clusters/biohazard/flux/kustomization.yaml b/kube/clusters/biohazard/flux/kustomization.yaml index b1ba3860..fef3b82a 100644 --- a/kube/clusters/biohazard/flux/kustomization.yaml +++ b/kube/clusters/biohazard/flux/kustomization.yaml @@ -116,6 +116,7 @@ resources: - ../../../deploy/apps/linkding/ - ../../../deploy/apps/collabora/ - ../../../deploy/apps/ocis/ + - ../../../deploy/apps/navidrome/ - ../../../deploy/vm/_kubevirt/ #- ../../../deploy/vm/_base/ - ../../../deploy/vm/ad/ diff --git a/kube/deploy/apps/navidrome/app/authentik.yaml b/kube/deploy/apps/navidrome/app/authentik.yaml new file mode 100644 index 00000000..d4cc6ab7 --- /dev/null +++ b/kube/deploy/apps/navidrome/app/authentik.yaml @@ -0,0 +1,22 @@ +--- +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: navidrome-authentik + namespace: authentik +spec: + ingressClassName: "nginx-internal" + rules: + - host: &host "${APP_DNS_NAVIDROME}" + http: + paths: + - pathType: Prefix + path: "/outpost.goauthentik.io" + backend: + service: + name: authentik + port: + name: http + tls: + - hosts: + - *host diff --git a/kube/deploy/apps/navidrome/app/es.yaml b/kube/deploy/apps/navidrome/app/es.yaml new file mode 100644 index 00000000..96d99798 --- /dev/null +++ b/kube/deploy/apps/navidrome/app/es.yaml @@ -0,0 +1,19 @@ +--- +# yaml-language-server: $schema=https://crds.jank.ing/external-secrets.io/externalsecret_v1beta1.json +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: &name navidrome-secrets + namespace: navidrome +spec: + refreshInterval: 1m + secretStoreRef: + kind: ClusterSecretStore + name: 1p + dataFrom: + - extract: + key: "Navidrome - ${CLUSTER_NAME}" + target: + creationPolicy: Owner + deletionPolicy: Retain + name: *name diff --git a/kube/deploy/apps/navidrome/app/hr.yaml b/kube/deploy/apps/navidrome/app/hr.yaml new file mode 100644 index 00000000..927f9e87 --- /dev/null +++ b/kube/deploy/apps/navidrome/app/hr.yaml @@ -0,0 +1,149 @@ +--- +apiVersion: helm.toolkit.fluxcd.io/v2beta2 +kind: HelmRelease +metadata: + name: &app navidrome + namespace: *app + labels: + nginx.ingress.home.arpa/type: auth +spec: + interval: 5m + chart: + spec: + chart: app-template + version: "2.6.0" + sourceRef: + name: bjw-s + kind: HelmRepository + namespace: flux-system + values: + controllers: + main: + type: deployment + replicas: 1 + pod: + labels: + prom.home.arpa/kps: allow + ingress.home.arpa/nginx-internal: allow + # egress.home.arpa/internet: "allow" + containers: + main: + image: &img + repository: ghcr.io/navidrome/navidrome + tag: 0.52.0@sha256:432b2e3a0e593031c2947fd2b33596b35fa319a835cb771b660f2bc2890de12a + env: + TZ: "${CONFIG_TZ}" + ND_BASEURL: "https://${APP_DNS_NAVIDROME}" + ND_MUSICFOLDER: /media + ND_DATAFOLDER: /config + ND_CACHEFOLDER: /config/cache + ND_PORT: &http "8080" + ND_COVERJPEGQUALITY: "100" + ND_DEFAULTTHEME: Dark + ND_ENABLEGRAVATAR: "false" + ND_IMAGECACHESIZE: "1GB" + ND_TRANSCODINGCACHESIZE: 5GB + ND_SEARCHFULLSTRING: "true" + ND_SUBSONICARTISTPARTICIPATIONS: "true" + ND_ENABLETRANSCODINGCONFIG: "${CONFIG_NAVIDROME_TRANSCODE_UI:=false}" + ND_UILOGINBACKGROUNDURL: https://raw.githubusercontent.com/JJGadgets/images/main/cover.png + ND_UIWELCOMEMESSAGE: "Welcome to JJGadgets Music." + ND_PROMETHEUS_ENABLED: "true" + ND_PROMETHEUS_METRICSPATH: /metrics + ND_REVERSEPROXYUSERHEADER: X-authentik-username + ND_REVERSEPROXYWHITELIST: "${IP_POD_CIDR_V4}" + envFrom: + - secretRef: + name: navidrome-secrets + securityContext: &sc + readOnlyRootFilesystem: true + allowPrivilegeEscalation: false + capabilities: + drop: ["ALL"] + resources: + requests: + cpu: "10m" + memory: "128Mi" + limits: + cpu: "3000m" + memory: "1Gi" + service: + main: + ports: + http: + port: *http + ingress: + main: + enabled: true + primary: true + className: nginx-internal + annotations: + nginx.ingress.kubernetes.io/auth-signin: |- + https://${APP_DNS_NAVIDROME}/outpost.goauthentik.io/start?rd=$escaped_request_uri + hosts: + - host: &host "${APP_DNS_NAVIDROME}" + paths: &paths + - path: / + pathType: Prefix + service: + name: main + port: http + tls: + - hosts: [*host] + persistence: + config: + enabled: true + existingClaim: navidrome-data + globalMounts: + - subPath: data + path: /config + nfs: + enabled: true + type: nfs + server: "${IP_TRUENAS}" + path: "${PATH_NAS_MEDIA}" + globalMounts: + - subPath: Music + path: /media + readOnly: true + tmp: + enabled: true + type: emptyDir + medium: Memory + globalMounts: + - subPath: "tmp" + path: "/tmp" + defaultPodOptions: + automountServiceAccountToken: false + enableServiceLinks: false + securityContext: + runAsNonRoot: true + runAsUser: &uid ${APP_UID_NAVIDROME} + runAsGroup: *uid + fsGroup: *uid + supplementalGroups: [6969] # NAS + fsGroupChangePolicy: Always + seccompProfile: { type: "RuntimeDefault" } + topologySpreadConstraints: + - maxSkew: 1 + topologyKey: kubernetes.io/hostname + whenUnsatisfiable: DoNotSchedule + labelSelector: + matchLabels: + app.kubernetes.io/name: *app + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: fuckoff.home.arpa/navidrome + operator: DoesNotExist + serviceMonitor: + main: + enabled: true + endpoints: + - port: http + scheme: http + path: "/api/v1/metrics" + interval: 1m + scrapeTimeout: 30s diff --git a/kube/deploy/apps/navidrome/ks.yaml b/kube/deploy/apps/navidrome/ks.yaml new file mode 100644 index 00000000..83cbc3f0 --- /dev/null +++ b/kube/deploy/apps/navidrome/ks.yaml @@ -0,0 +1,43 @@ +--- +apiVersion: kustomize.toolkit.fluxcd.io/v1 +kind: Kustomization +metadata: + name: navidrome-app + namespace: flux-system + labels: &l + app.kubernetes.io/name: "navidrome" +spec: + commonMetadata: + labels: *l + path: ./kube/deploy/apps/navidrome/app + dependsOn: + - name: navidrome-pvc +--- +apiVersion: kustomize.toolkit.fluxcd.io/v1 +kind: Kustomization +metadata: + name: navidrome-pvc + namespace: flux-system + labels: &l + app.kubernetes.io/name: "navidrome" +spec: + commonMetadata: + labels: *l + path: ./kube/deploy/core/storage/volsync/template + targetNamespace: "navidrome" + dependsOn: + - name: 1-core-storage-volsync-app + - name: 1-core-storage-rook-ceph-cluster + postBuild: + substitute: + PVC: "navidrome-data" + SIZE: "20Gi" + SC: &sc "file" + SNAP: *sc + ACCESSMODE: "ReadWriteMany" + RUID: !!str &uid | + ${APP_UID_NAVIDROME} + RGID: !!str | + ${APP_UID_NAVIDROME} + RFSG: !!str | + ${APP_UID_NAVIDROME} diff --git a/kube/deploy/apps/navidrome/kustomization.yaml b/kube/deploy/apps/navidrome/kustomization.yaml new file mode 100644 index 00000000..5eeb2657 --- /dev/null +++ b/kube/deploy/apps/navidrome/kustomization.yaml @@ -0,0 +1,6 @@ +--- +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: + - ns.yaml + - ks.yaml diff --git a/kube/deploy/apps/navidrome/ns.yaml b/kube/deploy/apps/navidrome/ns.yaml new file mode 100644 index 00000000..fb74aca9 --- /dev/null +++ b/kube/deploy/apps/navidrome/ns.yaml @@ -0,0 +1,10 @@ +--- +apiVersion: v1 +kind: Namespace +metadata: + name: navidrome + labels: + kustomize.toolkit.fluxcd.io/prune: disabled + pod-security.kubernetes.io/enforce: &ps baseline + pod-security.kubernetes.io/audit: *ps + pod-security.kubernetes.io/warn: *ps