Hybrid cloud cluster monorepo with Ansible, K8s, NixOS, and Terraform. cute.haus
ansible terraform nix k8s
1

Configure Feed

Select the types of activity you want to include in your feed.

migrate navidrome to k3s

Aly Raffauf (Jun 11, 2026, 11:46 AM EDT) bf9cfa07 9dfa1fd5

+262 -13
-7
k8s/charts/external-routes/values.yaml
··· 13 13 target: { ip: 100.81.61.31, port: 8096 } # jubilife 14 14 tls: { secretName: cute-haus-tls } 15 15 16 - - name: navidrome 17 - host: navidrome.cute.haus 18 - target: { ip: 100.95.27.71, port: 4533 } # snowpoint 19 - tls: { secretName: cute-haus-tls } 20 - middlewares: 21 - - default-forward-auth-navidrome@kubernetescrd 22 - 23 16 - name: plex 24 17 host: plex.cute.haus 25 18 target: { ip: 100.81.61.31, port: 32400 } # jubilife
+6
k8s/charts/navidrome/Chart.yaml
··· 1 + apiVersion: v2 2 + name: navidrome 3 + description: Navidrome music server 4 + type: application 5 + version: 0.1.0 6 + appVersion: "0.61.2"
+111
k8s/charts/navidrome/templates/deployment.yaml
··· 1 + apiVersion: apps/v1 2 + kind: Deployment 3 + metadata: 4 + name: {{ .Chart.Name }} 5 + labels: 6 + app: {{ .Chart.Name }} 7 + spec: 8 + replicas: 1 9 + strategy: 10 + type: Recreate 11 + selector: 12 + matchLabels: 13 + app: {{ .Chart.Name }} 14 + template: 15 + metadata: 16 + labels: 17 + app: {{ .Chart.Name }} 18 + spec: 19 + terminationGracePeriodSeconds: 30 20 + securityContext: 21 + fsGroup: 1000 22 + tolerations: 23 + - key: node.kubernetes.io/not-ready 24 + operator: Exists 25 + effect: NoExecute 26 + tolerationSeconds: 60 27 + - key: node.kubernetes.io/unreachable 28 + operator: Exists 29 + effect: NoExecute 30 + tolerationSeconds: 60 31 + containers: 32 + - name: {{ .Chart.Name }} 33 + image: deluan/navidrome:0.61.2 34 + imagePullPolicy: IfNotPresent 35 + command: 36 + - /bin/sh 37 + - -ec 38 + args: 39 + - | 40 + set -a 41 + . /run/secrets/navidrome/navidrome.env 42 + set +a 43 + exec /app/navidrome 44 + env: 45 + - name: ND_ADDRESS 46 + value: "0.0.0.0" 47 + - name: ND_PORT 48 + value: "4533" 49 + - name: ND_DATAFOLDER 50 + value: "/data" 51 + - name: ND_MUSICFOLDER 52 + value: "/mnt/Media/Music" 53 + - name: ND_DEFAULTTHEME 54 + value: "Auto" 55 + - name: ND_ENABLEUSEREDITING 56 + value: "false" 57 + - name: ND_SUBSONICARTISTPARTICIPATIONS 58 + value: "true" 59 + - name: ND_UIWELCOMEMESSAGE 60 + value: "Welcome to Navidrome @ k3s" 61 + - name: ND_EXTAUTH_USERHEADER 62 + value: "X-Forwarded-User" 63 + - name: ND_EXTAUTH_TRUSTEDSOURCES 64 + value: "100.64.0.0/10,10.42.0.0/16" 65 + ports: 66 + - name: http 67 + containerPort: 4533 68 + resources: 69 + requests: 70 + cpu: 50m 71 + memory: 256Mi 72 + limits: 73 + cpu: "1" 74 + memory: 1Gi 75 + volumeMounts: 76 + - name: data 77 + mountPath: /data 78 + - name: media 79 + mountPath: /mnt/Media 80 + readOnly: true 81 + - name: env 82 + mountPath: /run/secrets/navidrome 83 + readOnly: true 84 + startupProbe: 85 + httpGet: 86 + path: / 87 + port: http 88 + periodSeconds: 10 89 + failureThreshold: 60 90 + livenessProbe: 91 + httpGet: 92 + path: / 93 + port: http 94 + periodSeconds: 30 95 + readinessProbe: 96 + httpGet: 97 + path: / 98 + port: http 99 + periodSeconds: 10 100 + failureThreshold: 3 101 + volumes: 102 + - name: data 103 + persistentVolumeClaim: 104 + claimName: {{ .Chart.Name }}-data 105 + - name: media 106 + persistentVolumeClaim: 107 + claimName: {{ .Chart.Name }}-media 108 + readOnly: true 109 + - name: env 110 + secret: 111 + secretName: navidrome-env
+51
k8s/charts/navidrome/templates/ingress.yaml
··· 1 + apiVersion: networking.k8s.io/v1 2 + kind: Ingress 3 + metadata: 4 + name: {{ .Chart.Name }} 5 + labels: 6 + app: {{ .Chart.Name }} 7 + annotations: 8 + traefik.ingress.kubernetes.io/router.middlewares: default-forward-auth-navidrome@kubernetescrd 9 + spec: 10 + ingressClassName: traefik 11 + tls: 12 + - hosts: 13 + - "navidrome.cute.haus" 14 + secretName: cute-haus-tls 15 + rules: 16 + - host: "navidrome.cute.haus" 17 + http: 18 + paths: 19 + - path: / 20 + pathType: Prefix 21 + backend: 22 + service: 23 + name: {{ .Chart.Name }} 24 + port: 25 + number: 80 26 + --- 27 + apiVersion: networking.k8s.io/v1 28 + kind: Ingress 29 + metadata: 30 + name: {{ .Chart.Name }}-rest 31 + labels: 32 + app: {{ .Chart.Name }} 33 + annotations: 34 + traefik.ingress.kubernetes.io/router.middlewares: default-{{ .Chart.Name }}-drop-auth-header@kubernetescrd 35 + spec: 36 + ingressClassName: traefik 37 + tls: 38 + - hosts: 39 + - "navidrome.cute.haus" 40 + secretName: cute-haus-tls 41 + rules: 42 + - host: "navidrome.cute.haus" 43 + http: 44 + paths: 45 + - path: /rest/ 46 + pathType: Prefix 47 + backend: 48 + service: 49 + name: {{ .Chart.Name }} 50 + port: 51 + number: 80
+10
k8s/charts/navidrome/templates/middleware.yaml
··· 1 + apiVersion: traefik.io/v1alpha1 2 + kind: Middleware 3 + metadata: 4 + name: {{ .Chart.Name }}-drop-auth-header 5 + labels: 6 + app: {{ .Chart.Name }} 7 + spec: 8 + headers: 9 + customRequestHeaders: 10 + X-Forwarded-User: ""
+48
k8s/charts/navidrome/templates/pvc.yaml
··· 1 + apiVersion: v1 2 + kind: PersistentVolumeClaim 3 + metadata: 4 + name: {{ .Chart.Name }}-data 5 + labels: 6 + app: {{ .Chart.Name }} 7 + annotations: 8 + helm.sh/resource-policy: keep 9 + spec: 10 + accessModes: 11 + - ReadWriteOnce 12 + storageClassName: longhorn 13 + resources: 14 + requests: 15 + storage: 10Gi 16 + --- 17 + apiVersion: v1 18 + kind: PersistentVolume 19 + metadata: 20 + name: {{ .Chart.Name }}-media 21 + labels: 22 + app: {{ .Chart.Name }} 23 + spec: 24 + capacity: 25 + storage: 1Ti 26 + accessModes: 27 + - ReadOnlyMany 28 + persistentVolumeReclaimPolicy: Retain 29 + storageClassName: "" 30 + nfs: 31 + server: 100.81.61.31 32 + path: /mnt/Media 33 + readOnly: true 34 + --- 35 + apiVersion: v1 36 + kind: PersistentVolumeClaim 37 + metadata: 38 + name: {{ .Chart.Name }}-media 39 + labels: 40 + app: {{ .Chart.Name }} 41 + spec: 42 + accessModes: 43 + - ReadOnlyMany 44 + storageClassName: "" 45 + volumeName: {{ .Chart.Name }}-media 46 + resources: 47 + requests: 48 + storage: 1Ti
+11
k8s/charts/navidrome/templates/secret.yaml
··· 1 + {{- if .Values.secret }} 2 + apiVersion: v1 3 + kind: Secret 4 + metadata: 5 + name: navidrome-env 6 + labels: 7 + app: {{ .Chart.Name }} 8 + type: Opaque 9 + stringData: 10 + navidrome.env: {{ .Values.secret.env | quote }} 11 + {{- end }}
+14
k8s/charts/navidrome/templates/service.yaml
··· 1 + apiVersion: v1 2 + kind: Service 3 + metadata: 4 + name: {{ .Chart.Name }} 5 + labels: 6 + app: {{ .Chart.Name }} 7 + spec: 8 + type: ClusterIP 9 + selector: 10 + app: {{ .Chart.Name }} 11 + ports: 12 + - name: http 13 + port: 80 14 + targetPort: 4533
+9
k8s/helmfile.yaml
··· 242 242 values: 243 243 - values/secrets/forward-auth.yaml 244 244 245 + - name: navidrome 246 + namespace: default 247 + chart: ./charts/navidrome 248 + needs: 249 + - default/cluster-tls 250 + - default/forward-auth 251 + values: 252 + - values/secrets/navidrome.yaml 253 + 245 254 - name: paperless 246 255 namespace: default 247 256 chart: ./charts/paperless
+2
k8s/values/secrets/navidrome.yaml
··· 1 + secret: 2 + env: ref+sops://../secrets/navidrome.yaml#/env
-6
nix/hosts/jubilife.nix
··· 374 374 reverse_proxy jubilife:8686 375 375 ''; 376 376 377 - "navidrome.${tnet}".extraConfig = '' 378 - bind tailscale/navidrome 379 - encode zstd gzip 380 - reverse_proxy snowpoint:4533 381 - ''; 382 - 383 377 "ollama.${tnet}".extraConfig = '' 384 378 bind tailscale/ollama 385 379 encode zstd gzip