Host Your Own Music Streaming Server with Navidrome

Michael
6 min readJan 6, 2024

--

If you possess an extensive digital music collection like myself, managing and accessing your preferred artists and songs on your phone or media player can be a challenge. While platforms like Spotify and YouTube Music are popular choices, my personally curated music library, cultivated since 2001, deserves a dedicated solution. Enter Navidrome, an open-source music streaming server that empowers you to store your entire music collection and stream it seamlessly. Whether you prefer an intuitive, Spotify-like GUI or access via third-party apps on iOS or Android, Navidrome caters to your preferences.

Installation in a VMware Homelab Environment using Docker and Nginx Reverse Proxy

In this guide, I’ll walk you through the process of hosting Navidrome on-premise within a VMware homelab environment. While there are Software as a Service (SaaS) options and the possibility of hosting on cloud platforms like GCP, AWS, or Azure, this guide focuses on an on-premise setup.

Prerequisites:

  • Ubuntu 20.04.6 LTS VM with 1 vCPU and 1GB of memory.
  • Two virtual hard drives: one for the OS and another for music and settings storage.
  • Network setup with the server in the DMZ behind a Firewall.
My VM setup for Navidrome

Setting Up Data Drive and Scripts

After going through the steps and installing Ubuntu server we need to configure our second hard drive with GParted so that our data drive has a partition and file system setup.

I like to use GParted as its an easy and reliable way of managing partitions and adding space when required. Download the ISO from here and boot into it.

Create parition and file system with Gparted

Go to Device and select create partition table. Choose GPT and click apply.

Right click on unallocated and then click New. Choose the desired size and add any custom details and click add then complete the operations.

Once complete boot into your Ubuntu VM and the volume should be available in Ubuntu.

Available disks after format

Create a directory for the mounted volume:

sudo mkdir /media/HD/

Create scripts for automating drive mounting and disk space reporting:

sudo mkdir /opt/scripts/
sudo vim /opt/scripts/auto-mount.sh

Copy and past the below:
#!/bin/sh
sudo mount /dev/sdb1 /media/HD/

Next lets create a disk space script that will email us daily how much our space is in use on our drives:

sudo vim /opt/scripts/disk_space.sh

#!/bin/bash

# Set the recipient email address
recipient="youremailaddress@domain.co.uk”

# Set the SMTP server details
smtp_server="yoursmtpserveripaddress"
smtp_port=25

# Get the list of mounted volumes
volumes=($(df -h | awk 'NR > 1 {print $6}'))

# Create the email content header
email_content="Subject: Disk Space Report
From: yournaviserver@yourdomain.co.uk
To: $recipient

Dear User,

Disk space report:

"

# Loop through each volume and get the free space percentage
for volume in "${volumes[@]}"; do
free_space=$(df -h "$volume" | awk 'NR==2 {print $5}')
email_content+="Volume $volume: $free_space
"
done

# Create the email content footer
email_content+="Sincerely,
Your Server"

# Connect to the SMTP server and send the email
{
sleep 1
echo "EHLO localhost"
sleep 1
echo "MAIL FROM: <yournaviserver@yourdomain.co.uk>"
sleep 1
echo "RCPT TO: <$recipient>"
sleep 1
echo "DATA"
sleep 1
echo -e "$email_content"
echo "."
sleep 1
echo "QUIT"
} | telnet "$smtp_server" "$smtp_port"

# Display a message indicating the email has been sent
echo "Disk space report sent to $recipient"

Edit crontab for automatic execuction, I’ve set mine to automount the drive at reboot and to send me the disk space email at 6am each day.

sudo crontab -e
@reboot sh /opt/scripts/auto-mount.sh
0 6 * * * /opt/scripts/disk_space.sh

At this point it would be good to set up a static IP on your Ubuntu instance, install and set up OpenSSH server.

User Setup and Docker Installation

Now we need to create a user to run the Navidrome container and grant ownership permissions to the media directory:

sudo useradd navidrome
sudo chown navidrome: /media/HD

We need to install docker and docker-compose to run our Navidrome container.

For my use case I removed the docker engine that comes with the Ubuntu distro and installed it from the docker repository with the following steps from the official docker website:

Run the following command to uninstall all conflicting packages:

for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; donebash

Set up Docker’s apt repository:

# Add Docker's official GPG key:
sudo apt-get update
sudo apt-get install ca-certificates curl gnupg
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg

# Add the repository to Apt sources:
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get updatelist.d/docker.list > /dev/null

sudo apt-get update

Install latest docker engine:

sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

Verify installation was successful:

sudo docker run hello-world

Install docker compose:

DOCKER_CONFIG=${DOCKER_CONFIG:-$HOME/.docker}
mkdir -p $DOCKER_CONFIG/cli-plugins
curl -SL https://github.com/docker/compose/releases/download/v2.23.3/docker-compose-linux-x86_64 -o $DOCKER_CONFIG/cli-plugins/docker-compose

sudo docker compose version
Successful installation of Docker Engine and Docker Compose

Setup LastFM for Artwork retreival

Navidrome fetches album artwork for multiple sources which we can prioritise in our config. We can make API calls from Navidrome to Last.fm to retrieve album artwork.

  1. Sign up for a last.fm account here

2. Visit https://www.last.fm/api/account/create to register an api account.

3. Copy out the API Key and Shared Secret from the Account Created page as we need to add this into our compose file.

Installing Navidrome with docker compose

We are now ready to install Navidrome using docker compose.

The official docker compose file and further detail/configurations which you can use to suit your environment can be found here.

Below is my docker compose file:

version: "3"
services:
navidrome:
image: deluan/navidrome:latest
user: 1002:1002 # should be owner of volumes
ports:
- "4533:4533"
restart: unless-stopped
environment:
# Optional: put your config options customization here. Examples:
ND_SCANSCHEDULE: 1h
ND_LOGLEVEL: info
ND_SESSIONTIMEOUT: 24h
ND_BASEURL: ""
ND_PORT: 4533
ND_REVERSEPROXYWHITELIST: "0.0.0.0/0"
ND_LASTFM_APIKEY: yourapikey
ND_LASTFM_ENABLED: true
ND_LASTFM_SECRET: yoursecret
volumes:
- "/media/HD/NaviData:/data"
- "/media/HD/Music:/music:ro"

For the user we need to specify the user id of the user we created earlier.

Run id -u naviuser

For me this shows user 1002.

As you can see, I have added the ‘ND_REVERSEPROXYWHITELIST’ option and allowed all addresses. For some reason only specifying only my reverse proxy IP here did not work, which would be the most secure way of configuring this. However, depending on how you are exposing this either internally or to the internet we can use firewall rules to restrict to only the IP’s we want.

Sudo docker-compose up -d
Sucessful Navidrome install

Configure your reverse proxy server:

I am utilising NGINX to serve requests to my Navidrome server with the following configuration:

server {
listen 443 ssl;
server_name yourdomain.co.uk;
ssl on;

location / {
proxy_pass http://10.100.1.20:4533;
access_log /var/log/nginx/yourdomain.co.uk.log;
error_log /var/log/nginx/yourdomain.co.uk.log;

}
}

Full setup for NGINX reverse proxy is out of the scope of this guide. For my setup I use Lets Encrypt to deploy SSL certificates.

I also have enabled inbound SSL decryption and fail2ban as an extra layer security as I have used NAT to expose my reverse proxy server to the internet so I can access Navidrome from anywhere without VPN.

Iphone Apps

There are two Iphone apps I primarily use.

One is Substreamer which has the best UI, however it lacks an Apple Carplay app.

The other is Amperfy which has a bit more of a simpler UI but has a working Carplay integration.

Substreamer and Amperfy

--

--

No responses yet