summaryrefslogtreecommitdiff
path: root/f3s
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-02-04 19:23:55 +0200
committerPaul Buetow <paul@buetow.org>2026-02-04 19:23:55 +0200
commit7b23d27554fcf4ed561ffbc00fbfa4082a3c37f0 (patch)
tree43f014e26434c2c6d26678288348466d0d87a01d /f3s
parent2a29e6b4964639f19422a254498c2de89a7efbc2 (diff)
Add Navidrome music server deployment
Adds Navidrome music streaming server with: - Helm chart with deployment, service, ingress, and persistent volumes - Two PVs: data (10Gi) and music library (200Gi) - ArgoCD application for automated deployment - Ingress at navidrome.f3s.buetow.org - Justfile for operational commands
Diffstat (limited to 'f3s')
-rw-r--r--f3s/argocd-apps/services/navidrome.yaml28
-rw-r--r--f3s/navidrome/Justfile44
-rw-r--r--f3s/navidrome/helm-chart/Chart.yaml5
-rw-r--r--f3s/navidrome/helm-chart/README.md141
-rw-r--r--f3s/navidrome/helm-chart/templates/deployment.yaml55
-rw-r--r--f3s/navidrome/helm-chart/templates/ingress.yaml20
-rw-r--r--f3s/navidrome/helm-chart/templates/persistent-volume.yaml55
7 files changed, 348 insertions, 0 deletions
diff --git a/f3s/argocd-apps/services/navidrome.yaml b/f3s/argocd-apps/services/navidrome.yaml
new file mode 100644
index 0000000..aca2d4b
--- /dev/null
+++ b/f3s/argocd-apps/services/navidrome.yaml
@@ -0,0 +1,28 @@
+apiVersion: argoproj.io/v1alpha1
+kind: Application
+metadata:
+ name: navidrome
+ namespace: cicd
+ finalizers:
+ - resources-finalizer.argocd.argoproj.io
+spec:
+ project: default
+ source:
+ repoURL: http://git-server.cicd.svc.cluster.local/conf.git
+ targetRevision: master
+ path: f3s/navidrome/helm-chart
+ destination:
+ server: https://kubernetes.default.svc
+ namespace: services
+ syncPolicy:
+ automated:
+ prune: true
+ selfHeal: true
+ syncOptions:
+ - CreateNamespace=false
+ retry:
+ limit: 3
+ backoff:
+ duration: 5s
+ factor: 2
+ maxDuration: 1m
diff --git a/f3s/navidrome/Justfile b/f3s/navidrome/Justfile
new file mode 100644
index 0000000..e7003c8
--- /dev/null
+++ b/f3s/navidrome/Justfile
@@ -0,0 +1,44 @@
+NAMESPACE := "services"
+APP_NAME := "navidrome"
+
+# Show deployment status
+status:
+ @echo "=== Pods ==="
+ @kubectl get pods -n {{NAMESPACE}} | grep navidrome
+ @echo ""
+ @echo "=== Service ==="
+ @kubectl get svc -n {{NAMESPACE}} navidrome-service
+ @echo ""
+ @echo "=== Ingress ==="
+ @kubectl get ingress -n {{NAMESPACE}} navidrome-ingress
+ @echo ""
+ @echo "=== PVCs ==="
+ @kubectl get pvc -n {{NAMESPACE}} | grep navidrome
+ @echo ""
+ @echo "=== ArgoCD Status ==="
+ @kubectl get application {{APP_NAME}} -n cicd -o jsonpath='Sync: {.status.sync.status}, Health: {.status.health.status}' 2>/dev/null && echo "" || echo "Not found"
+
+# View logs
+logs lines="100":
+ kubectl logs -n {{NAMESPACE}} -l app=navidrome --tail={{lines}} -f
+
+# Port forward
+port-forward port="4533":
+ @echo "Forwarding navidrome to localhost:{{port}}"
+ kubectl port-forward -n {{NAMESPACE}} svc/navidrome-service {{port}}:4533
+
+# Trigger ArgoCD sync
+sync:
+ @echo "Triggering ArgoCD sync..."
+ @kubectl annotate application {{APP_NAME}} -n cicd argocd.argoproj.io/refresh=normal --overwrite
+ @sleep 2
+ @kubectl get application {{APP_NAME}} -n cicd -o jsonpath='Sync: {.status.sync.status}, Health: {.status.health.status}' && echo ""
+
+# Show ArgoCD application details
+argocd-status:
+ argocd app get {{APP_NAME}} --core
+
+# Restart
+restart:
+ @echo "Restarting navidrome..."
+ kubectl rollout restart -n {{NAMESPACE}} deployment/navidrome
diff --git a/f3s/navidrome/helm-chart/Chart.yaml b/f3s/navidrome/helm-chart/Chart.yaml
new file mode 100644
index 0000000..bf9e4b7
--- /dev/null
+++ b/f3s/navidrome/helm-chart/Chart.yaml
@@ -0,0 +1,5 @@
+apiVersion: v2
+name: navidrome
+description: A Helm chart for deploying Navidrome music server.
+version: 0.1.0
+appVersion: "latest"
diff --git a/f3s/navidrome/helm-chart/README.md b/f3s/navidrome/helm-chart/README.md
new file mode 100644
index 0000000..bee6058
--- /dev/null
+++ b/f3s/navidrome/helm-chart/README.md
@@ -0,0 +1,141 @@
+# Navidrome Music Server Kubernetes Deployment
+
+This directory contains the Kubernetes configuration for deploying Navidrome, a modern music server and streamer compatible with Subsonic/Airsonic clients.
+
+## Overview
+
+- **Application**: Navidrome
+- **Image**: `deluan/navidrome:latest`
+- **Namespace**: `services`
+- **Ingress**: `navidrome.f3s.buetow.org`
+- **Port**: 4533
+
+## Storage
+
+Navidrome requires two persistent volumes:
+
+1. **Data Volume** (`/data/nfs/k3svolumes/navidrome/data`): 10Gi
+ - Stores configuration, database (SQLite), cache, and metadata
+ - Mounted at `/data` in the container
+
+2. **Music Volume** (`/data/nfs/k3svolumes/navidrome/music`): 200Gi
+ - Stores your music library
+ - Mounted at `/music` in the container
+
+## Pre-Deployment Setup
+
+Before deploying, ensure the storage directories exist on the host:
+
+```bash
+mkdir -p /data/nfs/k3svolumes/navidrome/data
+mkdir -p /data/nfs/k3svolumes/navidrome/music
+```
+
+## Deployment
+
+The application is managed by ArgoCD. After committing changes to git and pushing to the r0 remote, ArgoCD will automatically sync and deploy the application.
+
+To manually trigger a sync:
+
+```bash
+just sync
+```
+
+## Initial Configuration
+
+1. After deployment, access Navidrome at `http://navidrome.f3s.buetow.org`
+2. On first access, you'll be prompted to create an admin account
+3. Configure settings as needed through the web UI
+
+## Adding Music
+
+Copy or sync your music files to the music volume on the host:
+
+```bash
+# On the host with the NFS share
+cp -r /path/to/your/music/* /data/nfs/k3svolumes/navidrome/music/
+```
+
+Navidrome will automatically scan for new music based on the `ND_SCANSCHEDULE` setting (default: hourly).
+
+## Management Commands
+
+Check deployment status:
+
+```bash
+just status
+```
+
+View logs:
+
+```bash
+just logs
+```
+
+Port forward for local access:
+
+```bash
+just port-forward
+```
+
+Restart the application:
+
+```bash
+just restart
+```
+
+## Features
+
+- Web-based music player
+- Compatible with Subsonic/Airsonic mobile apps
+- Automatic metadata fetching from Last.fm
+- Playlist support
+- Multi-user support
+- Transcoding support
+- Scrobbling to Last.fm
+
+## Client Apps
+
+Navidrome is compatible with various Subsonic clients:
+
+- **iOS**: play:Sub, substreamer
+- **Android**: DSub, Ultrasonic, substreamer
+- **Desktop**: Sublime Music, Sonixd
+- **Web**: Built-in web player
+
+## Configuration
+
+Environment variables can be adjusted in the deployment.yaml:
+
+- `ND_SCANSCHEDULE`: How often to scan for new music (default: 1h)
+- `ND_LOGLEVEL`: Logging level (info, debug, trace)
+- `ND_BASEURL`: Base URL if behind a reverse proxy
+
+See [Navidrome documentation](https://www.navidrome.org/docs/usage/configuration-options/) for all available options.
+
+## Troubleshooting
+
+Check pod status:
+
+```bash
+kubectl get pods -n services | grep navidrome
+```
+
+View detailed logs:
+
+```bash
+kubectl logs -n services -l app=navidrome --tail=200
+```
+
+Check persistent volume claims:
+
+```bash
+kubectl get pvc -n services | grep navidrome
+```
+
+## Security
+
+- Authentication is handled by Navidrome itself
+- No secrets are stored in git
+- User accounts are managed through the web UI
+- Consider enabling HTTPS in production
diff --git a/f3s/navidrome/helm-chart/templates/deployment.yaml b/f3s/navidrome/helm-chart/templates/deployment.yaml
new file mode 100644
index 0000000..b140537
--- /dev/null
+++ b/f3s/navidrome/helm-chart/templates/deployment.yaml
@@ -0,0 +1,55 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: navidrome
+ namespace: services
+spec:
+ replicas: 1
+ selector:
+ matchLabels:
+ app: navidrome
+ template:
+ metadata:
+ labels:
+ app: navidrome
+ spec:
+ containers:
+ - name: navidrome
+ image: deluan/navidrome:latest
+ ports:
+ - containerPort: 4533
+ env:
+ - name: ND_SCANSCHEDULE
+ value: "1h"
+ - name: ND_LOGLEVEL
+ value: "info"
+ - name: ND_BASEURL
+ value: ""
+ volumeMounts:
+ - name: navidrome-data
+ mountPath: /data
+ - name: navidrome-music
+ mountPath: /music
+ volumes:
+ - name: navidrome-data
+ persistentVolumeClaim:
+ claimName: navidrome-data-pvc
+ - name: navidrome-music
+ persistentVolumeClaim:
+ claimName: navidrome-music-pvc
+---
+apiVersion: v1
+kind: Service
+metadata:
+ labels:
+ app: navidrome
+ name: navidrome-service
+ namespace: services
+spec:
+ ports:
+ - name: web
+ port: 4533
+ protocol: TCP
+ targetPort: 4533
+ selector:
+ app: navidrome
diff --git a/f3s/navidrome/helm-chart/templates/ingress.yaml b/f3s/navidrome/helm-chart/templates/ingress.yaml
new file mode 100644
index 0000000..e8d94c6
--- /dev/null
+++ b/f3s/navidrome/helm-chart/templates/ingress.yaml
@@ -0,0 +1,20 @@
+apiVersion: networking.k8s.io/v1
+kind: Ingress
+metadata:
+ name: navidrome-ingress
+ namespace: services
+ annotations:
+ spec.ingressClassName: traefik
+ traefik.ingress.kubernetes.io/router.entrypoints: web
+spec:
+ rules:
+ - host: navidrome.f3s.buetow.org
+ http:
+ paths:
+ - path: /
+ pathType: Prefix
+ backend:
+ service:
+ name: navidrome-service
+ port:
+ number: 4533
diff --git a/f3s/navidrome/helm-chart/templates/persistent-volume.yaml b/f3s/navidrome/helm-chart/templates/persistent-volume.yaml
new file mode 100644
index 0000000..960bee3
--- /dev/null
+++ b/f3s/navidrome/helm-chart/templates/persistent-volume.yaml
@@ -0,0 +1,55 @@
+apiVersion: v1
+kind: PersistentVolume
+metadata:
+ name: navidrome-data-pv
+spec:
+ capacity:
+ storage: 10Gi
+ volumeMode: Filesystem
+ accessModes:
+ - ReadWriteOnce
+ persistentVolumeReclaimPolicy: Retain
+ hostPath:
+ path: /data/nfs/k3svolumes/navidrome/data
+ type: Directory
+---
+apiVersion: v1
+kind: PersistentVolumeClaim
+metadata:
+ name: navidrome-data-pvc
+ namespace: services
+spec:
+ storageClassName: ""
+ accessModes:
+ - ReadWriteOnce
+ resources:
+ requests:
+ storage: 10Gi
+---
+apiVersion: v1
+kind: PersistentVolume
+metadata:
+ name: navidrome-music-pv
+spec:
+ capacity:
+ storage: 200Gi
+ volumeMode: Filesystem
+ accessModes:
+ - ReadWriteOnce
+ persistentVolumeReclaimPolicy: Retain
+ hostPath:
+ path: /data/nfs/k3svolumes/navidrome/music
+ type: Directory
+---
+apiVersion: v1
+kind: PersistentVolumeClaim
+metadata:
+ name: navidrome-music-pvc
+ namespace: services
+spec:
+ storageClassName: ""
+ accessModes:
+ - ReadWriteOnce
+ resources:
+ requests:
+ storage: 200Gi