If you've got a folder full of MP3s and FLAC files sitting on a drive somewhere, streaming them to your phone shouldn't require a Spotify subscription or a Plex account tied to someone else's cloud. That's the gap Navidrome fills. It's a self-hosted music server that turns your own library into something you can stream from anywhere, with a clean web player and apps that speak the Subsonic protocol.
This guide walks you through installing Navidrome as an LXC container on Proxmox VE, using the Proxmox VE Community Scripts project. You don't need to know Docker, you don't need to hand-edit a systemd unit, and you don't need more than about ten minutes.
What You Will Learn
By the end of this tutorial you'll have a working Navidrome container running on your Proxmox VE host, with your music library mounted in and a login you control. Specifically, you'll learn how to:
- Deploy a Navidrome LXC container using the community install script
- Mount an existing music folder from your Proxmox host into the container
- Log in, scan your library, and confirm streaming works
- Read the config file so you can tweak settings later
- Fix the handful of problems that trip up almost everyone on their first install
What Is This Feature?
Navidrome is an open-source music server written in Go. It reads the audio files you point it at, builds a searchable library out of them (artists, albums, genres, playlists), and serves that library over the Subsonic API — a streaming protocol that's been around since 2004 and is supported by a long list of third-party apps.
In practice, that means you install Navidrome once on your server, and then use apps like Substreamer, play:Sub, DSub, or Symfonium on your phone to stream your library over the internet or your home network. There's also a built-in web player if you'd rather just use a browser.
We're running it inside an LXC container, which is Proxmox VE's version of a lightweight Linux container. Unlike a full virtual machine, an LXC container shares the host's kernel instead of emulating its own hardware, so it starts in a couple of seconds and uses a fraction of the RAM and disk a VM would need for the same job. For something like Navidrome, which is a single lightweight binary, a container is the obvious fit.
Why Would You Use It?
Most people land on Navidrome for one of three reasons. Either they're tired of paying a monthly fee to stream music they already own, they've got a large FLAC collection that a streaming service will happily re-encode into something worse, or they just want their own listening habits to stay off someone else's servers.
Compared to running Plex or Jellyfin just for music, Navidrome is noticeably lighter and built specifically around audio — it handles multi-disc albums, embedded artwork, ReplayGain loudness tags, and last.fm scrobbling without the video-server overhead. If your Proxmox box is already juggling a handful of other containers, that matters more than it sounds like it should.
It's also just fast. The whole application is a single compiled binary with no external database to manage — it uses SQLite by default — so a fresh library scan of a few thousand tracks takes seconds, not minutes.
Prerequisites
Before you start, make sure you've got the following in place:
- A working Proxmox VE host — this guide was tested on 8.x, and the community script also supports 9.x
- At least 2 GB of free disk space on the storage you'll use for the container's root disk, plus however much space your music library needs on top of that
- Root (or sudo) access to the Proxmox VE shell, either via the web UI's >_ Shell button on the node, or over SSH
- Your music files already sitting somewhere accessible to the Proxmox host — a local directory, a mounted NFS share, or a second disk
- Basic comfort typing a couple of commands into a terminal — nothing more advanced than that
You don't need to pre-create the container. The install script does that for you.
Step-by-Step Tutorial
Step 1: Open the Proxmox VE shell
Log into the Proxmox VE web interface, click your node's name in the left-hand tree (not a specific VM or container — the node itself), and click >_ Shell near the top right. This drops you into a root shell on the Proxmox host itself, which is where the install script needs to run.
Step 2: Run the Navidrome install script
Paste this into the shell and press Enter:
bash -c "$(curl -fsSL https://community-scripts.github.io/ProxmoxVE/ct/navidrome.sh)"
This pulls a shell script from the Proxmox VE Community Scripts project — a widely used collection of maintained install scripts for self-hosted apps — and runs it. It's the same project behind the Pi-hole, Uptime Kuma, and Immich scripts you may have already used on this same host.
Step 3: Choose default or advanced settings
The script asks whether you want Default Settings or Advanced Settings. Default gives you a Debian 12 container with 2 vCPU cores, 1 GB of RAM, and a 4 GB disk — plenty for Navidrome itself, though you'll want more disk if you plan to mount a huge library directly inside the container rather than bind-mounting it (more on that in a moment).
If you want to set a static IP, pick a specific storage pool, or change the container's resources up front, choose Advanced instead. For a first install, Default is fine — you can always adjust CPU, RAM, and disk later from the container's Resources tab in the Proxmox UI.
Step 4: Let the script finish and note the container's IP
The script downloads a Debian template if you don't already have one cached, creates the container, and installs Navidrome and its dependencies inside it. This usually takes two to four minutes depending on your internet connection. When it's done, it prints the container's IP address — write that down, you'll need it in a second.
Step 5: Mount your music library into the container
This is the step people skip and then wonder why their library is empty. Navidrome running inside a fresh LXC container can only see what's inside that container — it has no access to files sitting on your Proxmox host unless you explicitly share them.
The clean way to do this is a bind mount, which maps a folder on the Proxmox host directly into the container without copying anything. From the Proxmox shell, edit the container's config file (replace 100 with your container's actual ID, shown in the left-hand tree):
nano /etc/pve/lxc/100.conf
Add a line like this at the bottom:
mp0: /mnt/music,mp=/music
That tells Proxmox to take the host folder /mnt/music and mount it inside the container at /music. Adjust the host-side path to match wherever your music actually lives. Save the file, then restart the container for the mount to take effect:
pct reboot 100
Step 6: Open the Navidrome web interface
In a browser, go to http://<container-ip>:4533. Navidrome uses port 4533 by default. You should see a setup screen asking you to create the first admin account.
Step 7: Create your admin account and point Navidrome at your music
Pick a username and password — this becomes the first admin user. Once you're logged in, open Settings and confirm the music folder path is set to /music (or wherever you mounted it in Step 5). If it's not, you can also set it via the ND_MUSICFOLDER environment variable in the config file covered in the next section.
Step 8: Trigger a library scan
Navidrome scans automatically on startup, but if you added music after the container was already running, trigger a manual scan from the web UI — there's a scan icon in the top bar — or just restart the service:
systemctl restart navidrome
Give it a minute for a large library, then refresh the page. You should see your artists and albums populated, complete with embedded cover art if your files have it.
Commands Explained
Here's what each command you just ran actually does:
| Command | What it does |
|---|---|
bash -c "$(curl -fsSL ...)" | Downloads the install script and runs it immediately, without saving a copy to disk first |
nano /etc/pve/lxc/100.conf | Opens the container's configuration file directly on the Proxmox host — this is where bind mounts, resource limits, and other container-level settings live |
mp0: /mnt/music,mp=/music | Defines a mount point (Proxmox's term for a bind-mounted folder) — mp0 is just the first mount point slot; you'd use mp1, mp2, and so on for additional folders |
pct reboot 100 | Reboots LXC container ID 100 — pct is the Proxmox command-line tool for managing containers, similar to how qm manages VMs |
systemctl restart navidrome | Restarts the Navidrome service inside the container, which also triggers a fresh library scan on startup |
Common Errors
A few things come up often enough that they're worth calling out ahead of time.
Empty library after login. Almost always a missing or incorrect bind mount. Shell into the container with pct enter 100 and run ls /music — if that comes back empty, the mount point in Step 5 either points at the wrong host path or was never applied because the container wasn't rebooted.
"connection refused" when browsing to port 4533. The service probably hasn't finished starting, or it crashed on a bad config. Check its status with systemctl status navidrome inside the container — the output will usually tell you exactly what went wrong.
Cover art not showing up. Navidrome reads embedded artwork from the audio files themselves, or a cover.jpg/folder.jpg file sitting in the album folder. If your rips don't have either, you'll get a blank placeholder — that's expected behavior, not a bug.
Permission denied errors in the Navidrome log. This one trips people up because it looks like a Navidrome problem but it's really a Linux file-permissions problem. The user Navidrome runs as inside the container needs read access to the mounted folder. Unprivileged containers (the Proxmox default) map UIDs differently than the host, so a folder that's readable as root on the Proxmox host can still come up as permission-denied inside the container.
Troubleshooting
If the library scan finishes but tracks are missing, check the file extensions first — Navidrome supports the common formats (MP3, FLAC, OGG, M4A, WAV, and a few others) out of the box, but an unusual container format can get silently skipped. The scan log, viewable from Settings > About in the web UI, lists how many files were found versus indexed.
If the container itself won't boot after you edited the config file, double-check your syntax in /etc/pve/lxc/100.conf. A typo in the mount point line — a missing comma, an extra space — is enough to stop the container from starting at all. You can check the container's boot log with:
pct enter 100
If that command itself fails because the container is stopped, start it from the Proxmox web UI and watch the Task Log panel for the actual error text.
If performance feels sluggish on a very large library — tens of thousands of tracks — bump the container's RAM from the default 1 GB up to 2 GB in the Resources tab. SQLite handles most libraries fine at the default, but a bigger library benefits from the extra headroom during scans.
Best Practices
A few habits will save you trouble down the road:
- Mount your music as read-only from Navidrome's perspective if you're paranoid about accidental deletes — Navidrome never needs write access to your library, only read access
- Keep your music on a separate disk or NFS share rather than inside the container's root disk, so reinstalling or resizing the container never touches your actual files
- Back up the container the normal Proxmox way (vzdump, scheduled) — this captures the SQLite database with your playlists, ratings, and users, which live separately from the music files themselves
- If you're exposing Navidrome outside your home network, put it behind a reverse proxy with HTTPS rather than forwarding port 4533 directly — Navidrome doesn't handle TLS termination on its own
Honestly, most homelab users never need to touch the config file beyond the music folder path. Navidrome's defaults are sane, and the temptation to over-tune a music server usually isn't worth the time.
Frequently Asked Questions
Do I need a separate VM instead of an LXC container?
No. Navidrome is a single lightweight process with no special kernel requirements, which makes it a textbook case for a container rather than a full VM.
Can I stream my library outside my home network?
Yes, but you'll need to expose the container securely — either through a reverse proxy with a real SSL certificate, or a VPN like WireGuard or Tailscale. Don't just port-forward 4533 straight to the internet.
Does Navidrome support multiple users?
Yes. You can create additional accounts from the admin panel, each with their own playlists, play history, and ratings, all reading from the same shared library.
What apps can I use to stream from it on my phone?
Anything that speaks the Subsonic API. Substreamer and Symfonium are popular on Android and iOS; DSub and play:Sub are older but still work fine.
How do I update Navidrome later?
Re-run the same install script inside the Proxmox shell — the Community Scripts project detects an existing installation and offers to update it in place rather than creating a new container.
What happens to my playlists if I need to restore the container from a backup?
They come back with it. Playlists, ratings, and user accounts live in Navidrome's SQLite database inside the container, so a standard vzdump backup captures all of it alongside the OS.
Conclusion
Ten minutes and two commands gets you a music server that answers only to you — no algorithm deciding what you hear next, no library gaps because a label pulled a catalog. The bind mount in Step 5 is really the only part worth double-checking if something looks off afterward; everything else about Navidrome tends to just work.
From here, the next logical step for a lot of people is putting it behind a reverse proxy so it's reachable from outside the house — the Nginx Proxy Manager guide on this site covers exactly that setup if you want to take it further.