~ / Friendship Ended with Spotify, now NIXOS is my Best Friend

January 14, 2025

This year 2025, I wanted to go all out and end all my subscriptions on streaming platforms. I already own some instances of cloud vms running, for instance to run this blog in itself. I want to use the resources I already have to build a way for me to stream music from anywhere.

I use; A 2020 Macbook Air M1, my iphone, and a NIXOS desktop I have connected to the TV at home at all times. I wanted a way to have the NIXOS instance also be my mini media server.

nixos

Nixos is probably the future of linux package management. I have been using it on and off for the past 2 years, and I have to say I am impressed. It feels super sturdy and it has a huge package library, but it does have a steep learning curve compared to Debian or even Arch based Linux distributions. Learning it is worth it though, as once you have learnt how to edit its configuration file it will probably work forever. My box itself has gone through 3 or 4 version upgrades which cannot be said for many Ubuntu or Arch installs I have.

navidrome

I am using navidrome as my music server, it is open source unlike plex. And unlike jellyfin it is made specifically for music streaming. It supports the subsonic API which makes it compatible with a multitude of third party music player apps for mobile and desktop.

services.navidrome = {
    enable = true;
    settings = {
      Address = "0.0.0.0";
      Port = 4533;
      MusicFolder = "/mnt/LIB/Music";
      dataDir = "/mnt/LIB/navidrome";
      EnableSharing = true;
      CoverJpegQuality = 100;
      EnableUserEditing = true;
      ScanExclude = [ "lost+found" ];
      LastFM.Enabled = true;
      LastFM.ApiKey = "LASTFMKEY";
      LastFM.Secret = "LASTFM SECRET";
      LastFM.Language = "en";
    };
  };

  systemd.services.navidrome.serviceConfig = {
    User = lib.mkForce "emil";  # Run as 'emil' user
    Group = lib.mkForce "users";  # Use 'users' group
    ProtectHome = lib.mkForce false;
  };

Snippet of my navidrome settings for my navidrome install in my nix configuration file. Ensures the systemd service runs as my user and not root. Running as root and without ProtectHome causes weird things to happen including nixos storing the music library into the nix/store.

feishin

My music library in feishin, which is a great drop in replacement for the spotify desktop app. I have feishin both on my Mac and on my Linux Desktops. It feels infinitely faster than the Spotify app.

speed

It's UI is quite good and also relatively customizeable. In the screenshot below you can also spot one of my frustrations with Spotify. Missing tracks from albums, perhaps uncleared writing credits or just uncleared samples. I'd say around 3-5% of my favourite songs have dissapeared over the years. Two of my favourite Indonesian albums are both missing a song each!

compare

amperfy

For iPhone I have been using Amperfy which is great too. Supports offline playback/caching.

Reverse Proxy

network

I have all my personal devices on a Tailscale network, the whole reason why I wanted to try this project is to see how easy it could be to do a reverse proxy with nginx and tailscale. As I have a cloud server on digitalocean, I also put it on my tailscale network that way it can pass off all traffic on a specific port towards the ip+port running navidrome on my tailscale network. Granted this is one of the nice to have things about this setup, but now I can visit a specific url and be able to stream my whole music library from anywhere. Whether that device is in my tailscale network or not.

Soulseek

slskd

Soulseek is a peer2peer file sharing protocol/app. There are several different ways to use it, typically you would use it as desktop app like SoulseekQT or Nicotine+. However there is an app that is meant to be used as a web server called slskd and it is supported in the nixos package library.

systemd.services.slskd = {
    description = "Soulseek Daemon (slskd)";
    serviceConfig = {
      ExecStart = "${pkgs.slskd}/bin/slskd";
      Environment = [
        "USER=emil"
        "HOME=/home/emil"
      ];
      WorkingDirectory = "/home/emil/.local/share/slskd";
      User = lib.mkForce "emil";
      Group = lib.mkForce "users";
      ProtectHome = lib.mkForce false;
    };
    wantedBy = [ "multi-user.target" ];
  };

I have it setup to download files directly into my music library, so if I ever feel like I want to have access to a specific record on the go I can always add it to my music library like this. The files usually show up in real time.

Recently Added

Things To Consider

It would be nice to have a way to edit metadata from the browser and which isn't too awkward to use on the phone. Right now I just use puddletag on the Nixos desktop. I would also like to be able to add some sort of interface to download music from youtube for the the one off song I find thats not a record or is otherwise obscure (as I do listen to a fair bit of campursari and Indonesian folk music). I would also want to setup a way to scrobble and collect data on my listening habbits in a more robust way. But the current setup is already far exceeding my expectations.