Skip to main content

Navidrome

A self-hosted music streaming server compatible with the Subsonic API.

Navidrome is a lightweight, high-performance music server that scans your audio library and streams it through a web UI or any Subsonic-compatible client. It supports transcoding, scrobbling to Last.fm/ListenBrainz, and multi-user libraries. Self-hosting means streaming your own music collection without monthly subscription fees.

Alternatives considered

Cloud Hosted

ToolOpen SourceFree TierMonthly Cost
SpotifyNoLimited$12.99/mo
PlexNoLimitedFrom $4.99/mo

Self Hosted

ToolOpen SourceFull FeaturesNotes
SubsonicNoLimitedOriginal Subsonic API server; less maintained
Airsonic-AdvancedYesYesNavidrome predecessor; heavier

Installation

Architecture

  • Deployment: Single navidrome deployment in the navidrome namespace
  • Image: deluan/navidrome:0.60.3 (digest-pinned)
  • Storage: Longhorn PVC (navidrome-data, annotated k8up.io/backup: "true") for database; NFS PV from TrueNAS for the music library
  • Networking: HTTPRoute via internal gateway

Security

  • Runs as runAsUser: 1000, runAsNonRoot: true, allowPrivilegeEscalation: false, capabilities dropped
  • Longhorn PVC encrypted at rest via SOPS-managed keys

Updates

Managed by Renovate. Image is digest-pinned.

Data Management

  • Database: SQLite on navidrome-data Longhorn PVC (annotated k8up.io/backup: "true")
  • NFS: TrueNAS NFS PV for music library (read-only)
  • Backups: k8up Schedule backs up the Longhorn PVC to Hetzner S3 via restic.

User Management

No OIDC configured. User accounts managed through the Navidrome admin UI. Supports multi-user libraries.

Configuration Management

  • Spotify API credentials (ND_SPOTIFY_ID, ND_SPOTIFY_SECRET) from SOPS-encrypted secret
  • Scanner schedule and other settings configured via env vars in the Deployment
  • Longhorn encryption key from SOPS-encrypted secret

Administration

Usage

Browse and stream your music library via the web UI Connect mobile apps (DSub, Symfonium, Ultrasonic) using the Subsonic API endpoint. Navidrome automatically scans the NFS audio share for new files on the configured schedule.

Cluster-specific deviations from the above live in the per-cluster README — see k8s/apps/talos/navidrome/README.md.

Cluster Deployment

Navidrome — Talos cluster

Cluster-specific notes only. General product info, "why we use it", and alternatives live in docusaurus/docs/apps/navidrome.mdx.

Deviations from defaults

Defaults live in docusaurus/docs/apps/navidrome.mdx — document anything this cluster does differently here, with a one-line reason.

Kubernetes Metadata
  • Image: deluan/navidrome:0.62.0@sha256:c4b5cb36a790b3eb63ca6a68bbe2fe149c2d7fa2e586f7a480e61db630e6664b
Rendered manifests (kustomize build)
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
kustomize.toolkit.fluxcd.io/force: enabled
labels:
app.kubernetes.io/instance: navidrome
app.kubernetes.io/name: navidrome
name: navidrome
namespace: navidrome
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/instance: navidrome
app.kubernetes.io/name: navidrome
homepage: active
ingress: public
strategy:
type: Recreate
template:
metadata:
labels:
app.kubernetes.io/instance: navidrome
app.kubernetes.io/name: navidrome
homepage: active
ingress: public
spec:
containers:
- env:
- name: ND_SPOTIFY_ID
valueFrom:
secretKeyRef:
key: spotifyId
name: navidrome
- name: ND_SPOTIFY_SECRET
valueFrom:
secretKeyRef:
key: spotifySecret
name: navidrome
- name: ND_SCANNER_ENABLED
value: 'true'
- name: ND_SCANNER_SCHEDULE
value: 00 01,13 * * *
- name: ND_SCANINTERVAL
value: 12h
image: deluan/navidrome:0.62.0@sha256:c4b5cb36a790b3eb63ca6a68bbe2fe149c2d7fa2e586f7a480e61db630e6664b
name: navidrome
ports:
- containerPort: 4533
name: web
protocol: TCP
readinessProbe:
failureThreshold: 1
httpGet:
path: /
port: 4533
initialDelaySeconds: 2
periodSeconds: 3
successThreshold: 1
timeoutSeconds: 2
resources:
limits:
memory: 1500Mi
requests:
cpu: 10m
memory: 100Mi
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
privileged: false
volumeMounts:
- mountPath: /data/
name: navidrome-data
- mountPath: /music
name: navidrome-music
subPath: music
securityContext:
fsGroup: 1000
fsGroupChangePolicy: OnRootMismatch
runAsGroup: 1000
runAsNonRoot: true
runAsUser: 1000
seccompProfile:
type: RuntimeDefault
volumes:
- name: navidrome-data
persistentVolumeClaim:
claimName: navidrome-data
- name: navidrome-music
persistentVolumeClaim:
claimName: navidrome-truenas-nfs-audio