Navidrome on Proxmox LXC: Self-Hosted Music Streaming Without Spotify's Algorithm (2026)
homelab

Navidrome on Proxmox LXC: Self-Hosted Music Streaming Without Spotify's Algorithm (2026)

Ricardo Gil
August 17, 2026
13 min read
#Navidrome #Proxmox #Self-Hosting #Home Lab #Music Streaming

What Is Navidrome and Why Self-Host It?

Navidrome is a lightweight, open-source music streaming server that implements the Subsonic API β€” which means every decent music player app already talks to it out of the box. Think DSub, Symfonium, Ultrasonic, or Feishin on the desktop. You point your existing library at it, and within minutes you have a private Spotify that you own, with zero monthly fee, zero algorithmic recommendations pushing garbage at you, and zero bandwidth caps on your own network.

The case for self-hosting is straightforward: Spotify and Apple Music own your listening history, your playlists, and your discovery. If they pull a catalog or shut down, your curated library goes with them. Navidrome solves that permanently. It runs on a single binary, uses under 100 MB of RAM at idle, and handles multi-user households without breaking a sweat. For a Proxmox home lab, it is one of the best power-to-resource-cost ratios you will ever get out of an LXC container.

Prerequisites

  • Proxmox VE 8.x or 9.x β€” commands tested on both; PVE 9 users see the note on cgroup v2 below
  • LXC resources: 1 vCPU, 512 MB RAM, 4 GB root disk (music library stored separately)
  • Music storage: an NFS share, ZFS dataset, or external drive passed into the container β€” see the storage section
  • Network: a static IP or DHCP reservation for the container
  • Optional but recommended: Traefik reverse proxy for HTTPS (see the Traefik guide)

Hardware note: Navidrome does not transcode audio by default β€” it streams original files. If you want on-the-fly transcoding for mobile clients on cellular, you need FFmpeg installed. Even then, a Beelink EQ12 or similar N100 mini PC handles it effortlessly. For larger households with multiple simultaneous streams, the Beelink SER7 with its Ryzen 7 7840HS handles transcoding without breaking a sweat.

Step 1 β€” Create the LXC Container

From the Proxmox shell, create a Debian 12 unprivileged LXC container. Debian is preferred over Alpine because FFmpeg packaging is simpler and binary compatibility is better.

code
pct create 200 local:vztmpl/debian-12-standard_12.7-1_amd64.tar.zst \
  --hostname navidrome \
  --cores 1 \
  --memory 512 \
  --swap 512 \
  --net0 name=eth0,bridge=vmbr0,ip=dhcp \
  --rootfs local-lvm:4 \
  --unprivileged 1 \
  --features nesting=1 \
  --start 1

If you want to pass through a host directory (your music library on the Proxmox host), add a bind mount. Edit /etc/pve/lxc/200.conf and append:

code
mp0: /mnt/music,mp=/music,ro=1

The ro=1 flag mounts it read-only inside the container β€” Navidrome only reads files, never writes to them. Restart the container after editing the config:

code
pct restart 200

If your music lives on a ZFS dataset, create the dataset on the host first and pass it in the same way. ZFS datasets give you checksumming, compression, and instant snapshots β€” a LSI 9207-8i HBA card in IT mode is the standard way to attach spinning drives to a Proxmox node for ZFS pools.

Step 2 β€” Install Navidrome

Shell into the container:

code
pct enter 200

Update packages and install dependencies:

code
apt update && apt upgrade -y
apt install -y curl ffmpeg

Download the latest Navidrome binary. Check github.com/navidrome/navidrome/releases for the current version. The script below pulls the latest automatically:

code
NAVIDROME_VERSION=$(curl -s https://api.github.com/repos/navidrome/navidrome/releases/latest \
  | grep tag_name | cut -d'"' -f4 | tr -d v)
curl -L "https://github.com/navidrome/navidrome/releases/download/v${NAVIDROME_VERSION}/navidrome_${NAVIDROME_VERSION}_linux_amd64.tar.gz" \
  -o /tmp/navidrome.tar.gz
mkdir -p /opt/navidrome
tar xzf /tmp/navidrome.tar.gz -C /opt/navidrome
chmod +x /opt/navidrome/navidrome

Create a dedicated system user and the data directory:

code
useradd -r -s /bin/false -d /opt/navidrome navidrome
mkdir -p /var/lib/navidrome
chown -R navidrome:navidrome /opt/navidrome /var/lib/navidrome

Step 3 β€” Configure Navidrome

Navidrome reads a TOML config file. Create it at /opt/navidrome/navidrome.toml:

code
MusicFolder = "/music"
DataFolder = "/var/lib/navidrome"
Port = 4533
LogLevel = "info"
ScanSchedule = "@every 1h"
TranscodingCacheSize = "100MB"
SessionTimeout = "720h"

Key settings to understand:

  • MusicFolder β€” path to your music library inside the container (must match the bind mount above)
  • ScanSchedule β€” how often Navidrome rescans for new files; @every 1h is a good default balance between freshness and CPU overhead
  • TranscodingCacheSize β€” cache for transcoded audio; raise to 500 MB or more on larger libraries
  • SessionTimeout β€” 720h means client apps stay logged in for 30 days

For security hardening, you can also add BaseUrl = "/music" if you want to serve Navidrome at a sub-path behind a reverse proxy, and EnableSharing = false to disable the public share links feature if you do not use it.

Step 4 β€” Create the systemd Service

Create /etc/systemd/system/navidrome.service:

code
[Unit]
Description=Navidrome Music Server
After=network.target

[Service]
User=navidrome
Group=navidrome
Type=simple
ExecStart=/opt/navidrome/navidrome --configfile /opt/navidrome/navidrome.toml
WorkingDirectory=/opt/navidrome
TimeoutStopSec=20
KillMode=process
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target

Enable and start the service:

code
systemctl daemon-reload
systemctl enable --now navidrome
systemctl status navidrome

You should see active (running). Navidrome is now accessible at http://<container-ip>:4533. Check the logs if it fails to start:

code
journalctl -u navidrome -f

The most common failure at this stage is a permission error on the music folder β€” confirm the bind mount is accessible with ls -la /music inside the container.

Step 5 β€” First Login and Library Scan

Open a browser and navigate to http://<container-ip>:4533. Navidrome prompts you to create an admin account on first run β€” set a strong password here. After login, head to Settings β†’ Scanning and click Scan All to trigger an immediate full library scan.

Depending on library size, this takes anywhere from 30 seconds (a few hundred albums) to a few minutes (tens of thousands of tracks). Navidrome reads ID3 tags, so well-tagged files appear with correct artist, album, and embedded artwork. If your tags are a mess, run MusicBrainz Picard on your library first β€” it makes a dramatic difference.

To add more users (family members, guests with read-only access), go to Admin β†’ Users β†’ New User. Each user gets independent play count history, playlists, and starred items. The admin can set per-user bitrate limits β€” useful if a guest is hammering the transcoder.

Step 6 β€” Connect Client Apps

The Subsonic API that Navidrome exposes is one of its biggest strengths. It has been the standard protocol for self-hosted music since 2008, and virtually every serious music player supports it. Recommended clients organized by platform:

  • Android: Symfonium (best UI, paid), DSub (free, proven), Ultrasonic (free, open-source)
  • iOS: Amperfy (free, polished), play:Sub (paid)
  • Desktop (Linux/macOS/Windows): Feishin (cross-platform Electron app, free), Strawberry Music Player (native, free)
  • Web browser: Navidrome ships a built-in web UI β€” no client install needed for casual use

In any Subsonic-compatible client, set the server URL to http://container-ip:4533 (or your HTTPS domain after reverse proxy setup), and use the admin credentials. The Subsonic API version Navidrome reports is 1.16.1 β€” all modern clients support this.

Step 7 β€” Reverse Proxy with HTTPS

HTTP-only is fine for LAN-only use, but most Subsonic clients require HTTPS when connecting over the internet. The fastest path is Traefik with Let's Encrypt DNS-01 β€” covered in full in the Traefik on Proxmox LXC guide. Add a dynamic config entry pointing at the Navidrome container IP on port 4533.

Alternatively, use Cloudflare Tunnels for zero-port-forwarding HTTPS without a public IP β€” the Cloudflare Tunnels guide covers this end-to-end. For quick Nginx Proxy Manager setups, the upstream is simply http://navidrome-container-ip:4533 with WebSocket support enabled.

Post-Install Tips

Backup Strategy

Navidrome stores all its state in a single SQLite file: /var/lib/navidrome/navidrome.db. This contains users, playlists, play counts, starred tracks, and the scan cache. Back it up at two levels: the LXC container via Proxmox Backup Server (daily, retain 7 days), and the database file itself via a cron job copying it to your NAS or MinIO bucket:

code
0 3 * * * sqlite3 /var/lib/navidrome/navidrome.db ".backup /backup/navidrome-$(date +\%Y\%m\%d).db"

Your music files live on the host and are not inside the container, so the LXC backup is small and fast.

Storage Recommendations

For a serious music collection β€” 10,000 albums or more β€” you want purpose-built NAS drives. Seagate IronWolf 4TB drives are designed for continuous read access and NAS vibration environments. Pair two in a ZFS mirror (RAID-1) for data redundancy. For the OS and Navidrome binary, a Samsung 870 EVO SSD as the Proxmox boot drive keeps the node fast without paying NVMe prices for a boot disk. The Crucial P3 Plus NVMe is a solid mid-range choice if your board has an M.2 slot to spare.

Transcoding on Constrained Hardware

If you are running Navidrome on a low-power node like the Beelink EQ12 with the N100, FFmpeg transcoding for multiple simultaneous streams can push CPU usage up. Limit concurrent transcoding sessions in Navidrome's admin settings, or upgrade to a node with more single-core performance. The Beelink SER7 handles a household of concurrent transcoders without thermal throttling.

Networking Tip

If you have multiple Proxmox nodes or a dedicated NAS on the same rack, consider upgrading your switch to a managed unit for VLAN segmentation and link aggregation. The TP-Link TL-SG108E handles 8 ports with full 802.1Q VLAN support for under $30 β€” it is the go-to managed switch for small home labs. For larger setups, the TP-Link TL-SG1016DE gives you 16 ports for around $80.

Proxmox VE 9 Note

PVE 9 dropped cgroup v1. If you hit permission issues with bind mounts in unprivileged containers, check that the UID/GID of the navidrome user maps correctly using lxc.idmap entries in the container config. The default unprivileged mapping (UID 100000–165535 on the host) typically works without adjustment, but it is worth verifying if the music folder returns permission denied errors.

When NOT to Self-Host Navidrome

Navidrome is excellent, but it is not the right answer for every situation. Skip it if any of these apply to you.

You listen primarily to new releases and curated playlists. Navidrome streams music you already own β€” it cannot pull new albums from a streaming catalog. If 80% of your listening is discovering new music via algorithmic playlists, Spotify wins on that axis.

You have no organized local library. Navidrome depends entirely on your file collection and ID3 tags. A mess of untagged MP3s in random folders produces a frustrating experience. Plan a MusicBrainz Picard session before deploying Navidrome, or the library view will be useless.

You need podcast and audiobook support. Navidrome is music-only. For podcasts and audiobooks, Audiobookshelf is the self-hosted answer β€” it handles both formats well and runs cleanly in its own LXC container.

Non-technical family members are the primary users. Getting someone to install and configure a Subsonic client app can turn into a support burden. Navidrome's built-in web UI helps significantly, but it is not as frictionless as opening Spotify on a smart TV. If this is your situation, assess whether the support overhead is worth the cost savings.

FAQ

Does Navidrome work with Sonos or Chromecast?

Yes, with caveats. Navidrome itself does not have native casting support built in. The desktop client Feishin supports Chromecast natively. For Sonos, the Symfonium Android app supports Sonos routing through its own cast layer. There is no official first-party Sonos integration β€” if that is a hard requirement, consider Plex with its dedicated Sonos app instead.

How does Navidrome handle large libraries β€” 100,000 tracks or more?

It handles them fine. The initial scan of a 100,000-track library takes 10 to 30 minutes depending on disk I/O speed. After that, incremental scans on the hourly schedule are fast since only changed files are processed. Memory usage scales modestly β€” expect 200 to 400 MB RAM at steady state for a very large library, still within the 512 MB container allocation. If you push past 200,000 tracks, bump the container memory to 1 GB.

Can I run Navidrome alongside other services in the same LXC?

Technically yes, but it is not recommended. Keep Navidrome in its own container for clean resource tracking, easier snapshots, and isolated upgrades. LXC containers on Proxmox are cheap β€” 512 MB RAM and 4 GB disk for a dedicated container is a trivial cost.

What music file formats does Navidrome support?

Any format FFmpeg can decode: MP3, FLAC, AAC, OGG Vorbis, OPUS, WAV, AIFF, M4A, WavPack, and more. FLAC is the recommended archival format β€” a Seagate IronWolf 8TB holds roughly 50,000 standard FLAC albums at typical sizes.

How does Navidrome compare to Plex or Jellyfin for music?

Plex and Jellyfin are full media servers where music is one feature among many. Navidrome is music-only and does it much better β€” richer metadata handling, correct album artist vs. track artist disambiguation, proper compilation handling, better Last.fm scrobbling, lower resource use, and the entire Subsonic API client ecosystem. If music is your primary use case, Navidrome is the correct tool. If you want one server for video, photos, and music together, Jellyfin is the better choice.

Does Navidrome support Last.fm scrobbling?

Yes, natively. Go to Settings β†’ Personal β†’ Last.fm and enter your credentials. Every play is scrobbled automatically. This works per-user, so multiple household members each scrobble to their own Last.fm accounts independently β€” no shared play history bleeding between accounts.

Wrapping Up

Navidrome is one of those self-hosted apps that earns its place immediately β€” lightweight enough to forget it is running, capable enough to fully replace a Spotify subscription for anyone with an existing music library. The Proxmox LXC setup takes under 15 minutes from a fresh container to streaming music on your phone. The resource footprint is negligible, and the Subsonic client ecosystem means you are never locked into any particular app.

For a home lab that already runs Jellyfin for video, Navidrome for audio is the natural complement β€” two dedicated, lightweight servers instead of one bloated general-purpose media server trying to do everything. The hardware investment is minimal: the same Beelink EQ12 running your Proxmox node already handles Navidrome without measurable additional load.

If you want HTTPS without opening ports, the Cloudflare Tunnels guide is the cleanest next step. Questions about the setup? Drop them in the comments below.

πŸ“¬Weekly Newsletter

Get the best home lab & AI content

No spam. One email per week. Unsubscribe anytime.

Share this article