A note before we start: the “I” in this essay is a composite — an archetypal indie developer stitched together from countless real threads on r/selfhosted, Lemmy, and Hacker News, and from the very real software and tradeoffs those communities live with. The frustrations are real. The tools are real. The steps are real enough that you could follow them yourself. The person is a stand-in. Think of him as every developer who has ever looked at a subscription renewal email and thought, “I could just build this myself.” Some of us actually do.
The email that broke me
The email arrived on a Tuesday, wedged between a GitHub notification and a reminder about a dentist appointment. “We’re updating the price of your Premium plan.” I had seen versions of this before — a dollar here, a dollar there, always framed as an investment in “an even better experience.” But this one tipped me over. My individual plan was going to $12.99 a month. When I first signed up, years ago, it had been $9.99, a number so stable it felt like a law of physics. In early 2026, under new leadership, Spotify pushed US Premium to $12.99, and the internet did what it always does: half the users shrugged, half of them threatened to leave, and almost none of them actually did.
I want to be honest about why the price hike bothered me, because it wasn’t really the money. Thirteen dollars a month is less than two coffees. If the service had felt like mine, I’d have paid it without blinking. What bothered me was the slow, dawning realization that after nearly a decade of paying, I owned exactly nothing. Not a single track. If I stopped paying, my entire musical life — the playlists I’d curated over years, the albums I’d fallen asleep to, the deep cuts I’d rescued from obscurity — would evaporate the instant my card got declined. I had been renting my own memories.
And then there was the other thing, the thing that had been nagging at me for a while. I’d read enough by then to know the numbers. Streaming services pay artists somewhere in the neighborhood of $0.003 to $0.005 per stream. Do the arithmetic on that. An independent musician needs somewhere north of 250,000 streams a month just to clear a modest minimum wage, and that’s before the label, the distributor, and the aggregator take their cuts. Meanwhile my monthly fee went up and their per-stream rate stayed flat. The money was going somewhere, and it wasn’t going to the people making the thing I actually loved.
I’m a programmer. My whole professional life is built on the premise that when a system frustrates you, you can, in principle, take it apart and build a better one. So one night, mildly annoyed and moderately caffeinated, I opened a terminal and started reading. Six weeks later I had cancelled Spotify. This is the story of what I built, what it cost me — in money, in time, in convenience — and whether it was worth it. Spoiler: mostly yes, with an asterisk I’ll be honest about.
Three frustrations, one decision
Let me lay out the case against my old setup plainly, because I think the frustration is the most relatable part of this, more than any Docker command I’m about to inflict on you.
The price only goes one direction. Every service I subscribed to had learned the same trick: onboard cheap, then ratchet. Not fast enough to trigger a mass exodus, just steadily enough that five years later you’re paying 30% more for a product that, functionally, does the same thing it did on day one. The subscription economy runs on inertia, and I was its ideal customer.
Everything sounded the same. This one is harder to quantify, but every heavy streaming user knows the feeling. The algorithm is extraordinarily good at giving you more of what you already like, which sounds wonderful until you realize it has quietly built you a very comfortable, very small room and locked the door. My “discovery” playlists kept surfacing tracks that were statistically adjacent to my history and emotionally identical to each other — the same mid-tempo, reverb-drenched, playlist-optimized sound engineered to never make you skip and never make you feel much of anything. I hadn’t stumbled onto a weird, life-changing record in years. The machine had optimized surprise out of my life.
I owned nothing. I’ve said it already but it bears repeating because it’s the load-bearing wall of this whole essay. My library was a lease. My playlists were tenants. The moment the business model changed, or a licensing deal fell through, or the company decided a feature I loved was no longer strategic, it was gone, and I had no recourse. I’ve watched enough services get acquired and gutted to know how that story ends.
The decision, when I finally made it, wasn’t dramatic. It was more like the moment you decide to leave a party — a quiet internal click, and then just the logistics. The logistics, it turns out, are the interesting part.
What “build your own streaming service” actually means in 2026
Here’s the thing that surprised me most: this is a solved problem. It has been solved for years by a quiet, stubborn community of self-hosters who never accepted the premise that music has to be a rental. When people say “I built my own Spotify,” they are almost never writing a streaming engine from scratch. They are assembling a stack of mature, open-source components, most of which have been battle-tested for the better part of a decade. My job wasn’t to invent anything. It was to choose well and wire things together.
The stack breaks down into four decisions:
- The server — the software that indexes your music, transcodes it on the fly, and speaks a streaming protocol to clients.
- The library — the actual files, and crucially, the metadata that makes tens of thousands of files navigable instead of a junk drawer.
- The clients — the apps on your phone, laptop, and wherever else you listen.
- Remote access — the piece that lets you stream your home library from a train, which is the whole reason Spotify beat owning MP3s in the first place.
Let me walk through each the way I actually approached them, mistakes included.
Choosing the server: Navidrome, and the road not taken
I spent an embarrassing amount of time on this decision before realizing it barely mattered, because the ecosystem is standardized in a way that lets you swap servers later. The unifying magic is an API. Back in the 2000s a piece of software called Subsonic defined a music-streaming API, and even though Subsonic itself went proprietary, the API became a de facto standard. Today there’s an actively maintained, community-driven successor called OpenSubsonic that extends it. Because everyone speaks this common protocol, any compliant server works with any compliant client. It’s the closest thing self-hosted music has to a lingua franca, and it’s the reason this whole world is as pleasant as it is.
My realistic options in 2026:
- Navidrome — a modern, lightweight server written in Go, laser-focused on music, with a clean web UI and rock-solid OpenSubsonic support. It’s the community darling, and for good reason.
- Jellyfin — the big open-source media server that does movies, TV, and music. If you want one box for everything, it’s compelling. But its music experience, while much improved, has always felt like a feature rather than the whole point.
- Funkwhale — a fascinating, more ambitious project built on ActivityPub, the same protocol behind Mastodon. It’s a federated music platform, meaning servers can share libraries and you can follow public “channels.” More social, more heavyweight, more moving parts.
- Airsonic-Advanced — the venerable community fork of the original open-source Subsonic, in Java. Stable and proven, but it feels its age next to Navidrome.
I went with Navidrome. It does one thing, it does it beautifully, its memory footprint is small enough to run comfortably on a Raspberry Pi, and the client app ecosystem around it is enormous. The comparison writeups I read kept landing on the same summary: if music is your primary goal, Navidrome; if you want one server for all media, Jellyfin. Music was my primary goal.
Standing it up was almost anticlimactic. Navidrome ships as a single binary and an official Docker image. My entire server definition was a dozen lines of docker-compose.yml: point it at a folder for the music, point it at a folder for its database, expose a port, set a couple of environment variables. docker compose up -d, wait for the first scan, and there it was — a clean web player at an address on my home network, showing an empty library, waiting to be fed. I ran it on a mini PC I already had idling in a closet, an old machine with a big cheap hard drive bolted on. Total additional hardware cost: zero, because I’d been hoarding that box for exactly this kind of project.
The empty library is where the real work started. A server is just a lens. It’s only as good as what you point it at.
The library: where the real work lives
I had music already — years of it, scattered across an old iTunes folder, a “downloads” graveyard, some FLAC rips from CDs I’d bought in college and long since given away. Maybe eight thousand tracks. When I first pointed Navidrome at that folder, the result was a disaster. Albums split into fragments because one track had a slightly different album-artist tag. “Unknown Artist” everywhere. Duplicate covers. Compilations that scattered into forty one-track “albums.” The music was there; the metadata was garbage, and metadata is what turns a pile of files into a browsable library.
This is the part nobody tells you about, and it’s the part that separates a toy from a real streaming service. Two tools fixed it, and learning them was the single highest-leverage thing I did.
MusicBrainz Picard was the first. MusicBrainz is a massive open, community-run music encyclopedia — think Wikipedia for song metadata, with a stable identifier for essentially every recording ever released. Picard is its desktop tagging app. You drag in a folder of messy files, Picard “fingerprints” the actual audio using AcoustID (it listens to the sound, so it works even when the existing tags are wrong or absent), matches each track against the MusicBrainz database, and rewrites clean, consistent tags — correct artist, album, track number, release date, and crucially the MusicBrainz IDs that let everything downstream stay consistent. It also grabbed proper cover art. Running my whole library through Picard was tedious the first time, an evening of clicking and verifying, but it transformed the collection.
beets was the second, and this is the tool that made me feel like I’d genuinely upgraded past Spotify rather than merely replaced it. beets is a command-line music library manager, and it is a programmer’s dream. You run beet import, point it at new music, and it does the MusicBrainz matching automatically, moves and renames files into a consistent folder structure you define, and writes clean tags — all scriptable, all repeatable. But the real power is its plugin ecosystem: plugins to fetch lyrics, to pull genre tags from Last.fm, to calculate ReplayGain so your quiet folk record and your loud punk record play at the same volume, to detect and quarantine duplicates, to fetch high-resolution cover art. My import workflow became a single command, and every new album that entered my library came out the other side clean, correctly named, correctly tagged, and instantly visible in Navidrome after a rescan.
I want to dwell on how good this feels, because it’s the emotional core of the whole switch. On Spotify, my library was a set of pointers to someone else’s database, and I had no control over any of it. With beets and Picard, I am the database administrator of my own musical life. When a tag is wrong, I fix it, and it stays fixed. When I want everything organized Artist/Year - Album/Track, it is. This is what ownership actually feels like at the level of daily use: not a legal abstraction, but the simple fact that the thing does what I tell it to.
The clients: listening everywhere
A server in a closet is useless if you can’t listen from your couch, your desk, and a bus. This is where the OpenSubsonic standard pays off spectacularly, because I wasn’t limited to one official app designed by one company’s product team. There are, at last count, something like eighty compliant clients, and I got to pick the best one for each context. That plurality is itself a feature — no single company can degrade my experience, because if one app stagnates I just switch to another and my server doesn’t care.
Here’s what I actually settled on:
- On my iPhone: Amperfy. A polished, open-source iOS player with proper offline sync, CarPlay support, an equalizer, and ReplayGain. Offline sync was non-negotiable for me — I download my most-played albums to the phone so a subway with no signal is no different from my living room. There’s also play:Sub, a well-loved paid iOS client, and substreamer, a free cross-platform option. On Android the equivalent conversation is Symfonium (a genuinely excellent paid player with a ludicrous 256-band equalizer, Android Auto, and Wear OS support) or the long-standing DSub.
- On my laptop: Feishin and, on lighter days, Supersonic — both modern cross-platform desktop clients built on the MPV engine for high-quality gapless playback. Feishin’s smart-playlist editing and lyrics support make it my main “sit down and dig through the collection” app.
- On the web: Navidrome’s own built-in player, which is genuinely good and means any browser on any machine is a fallback client with zero installation.
Every one of these apps points at the same server and sees the same library, the same playlists, the same play counts. I got the “it just works everywhere” experience that made Spotify feel magical — except the magic is running on my hardware and answering to me.
Scrobbling deserves a mention here, because it solved my “discovery” anxiety. All these clients can scrobble to Last.fm or ListenBrainz — services that log what you play and, in ListenBrainz’s case, feed an open recommendation system. So I didn’t lose listening history or recommendations by leaving Spotify. I just moved them to an open platform that doesn’t hold my library hostage.
Remote access: the piece that makes it real
Here’s the hurdle that stops most people, and it’s a legitimate one. Streaming from home while you’re at home is trivial. Streaming from a train is the entire value proposition of Spotify, and it requires exposing your server to the internet somehow. Do that carelessly and you’ve turned your closet PC into an open door for the entire internet. I was not going to port-forward a homemade server straight onto the public web; that’s how you end up as a cautionary tale.
There are two sane approaches, and I want to describe both because the choice reflects a real tradeoff.
Option one, the one I chose: Tailscale. Tailscale builds a private mesh network (a “tailnet”) between your devices using WireGuard under the hood. Install it on the server and on my phone and laptop, and suddenly my devices can all reach each other over an encrypted connection as if they were on the same local network, no matter where in the world they physically are. Nothing is exposed to the public internet at all. My phone on hotel Wi-Fi reaches Navidrome at a stable private address, the traffic is encrypted end to end, and there’s no attack surface for strangers because strangers aren’t on my tailnet. Setup was maybe fifteen minutes. This is, by a wide margin, the easiest and safest option, and it’s what I’d recommend to anyone who isn’t specifically trying to share their library with a wider circle.
Option two: a reverse proxy with a real domain. If you want a public URL — say, to let a few friends or family stream from your library without installing Tailscale — you put a reverse proxy like Caddy (or Traefik, or nginx) in front of Navidrome. Caddy is lovely because it fetches and renews HTTPS certificates automatically, so you get proper encryption with almost no configuration. You point a domain at your home IP, let Caddy terminate TLS, and optionally layer on extra authentication. It’s more powerful and more social, but it’s also more surface area to secure and maintain, and you’re now responsible for keeping that door locked.
For a purely personal setup, Tailscale wins on nearly every axis. The mental relief of knowing there is simply no public endpoint to attack was worth more to me than the convenience of a shareable link.
Sourcing music ethically — the part I care about most
A streaming service you own is only as good as the music in it, and this is where I had to think hardest, because “own your music” can quietly become “pirate your music,” and that was never the point. The whole reason I left was that artists weren’t getting paid. Building a library by robbing them would be a special kind of hypocrisy. So I set a rule: every track in my library gets there through a channel that actually compensates the artist, or is explicitly free to share. Here’s how I filled it.
Bandcamp became my main record store. When you buy an album on Bandcamp, you get an actual, DRM-free download — you choose the format, up to lossless FLAC — and a substantial majority of the money goes directly to the artist. The files are yours. I drop them into my beets import folder and thirty seconds later they’re in my Navidrome library, tagged and ready, playing on my phone. The difference in how that transaction feels is night and day: instead of a fraction of a penny per stream, I’m handing an artist eight or ten dollars for a record I’ll own forever. On Bandcamp Fridays, when the platform waives its cut, even more of it reaches them. I’ve bought more music in six months this way than in the previous three years of streaming, and I’ve spent less overall.
My own CDs and rips. All those albums I’d bought over the years — I re-ripped the ones I still had to FLAC and folded them in. Music you legally own, ripped for personal use, is exactly what this system is built to serve.
The Free Music Archive and Creative Commons. For discovery and for filling in the corners, there’s a whole legitimate world of freely licensed music. The Free Music Archive offers curated, legal downloads, much of it under Creative Commons licenses that explicitly permit sharing. Netlabels, the Internet Archive‘s live music collections, and artists who release directly under CC licenses gave me a steady stream of genuinely new-to-me music to explore — the serendipity Spotify’s algorithm had stopped providing. There’s something poetic about rediscovering musical surprise through the free and open corner of the internet, the same ethos that built the software I was running.
The upshot is that my library grew slower than a Spotify catalog of a hundred million tracks — obviously — but every single thing in it is there because I chose it and paid for it. My collection isn’t infinite. It’s mine, and it’s curated by a human being with taste, namely me, instead of a licensing spreadsheet.
What actually got better
Six months in, here’s the honest ledger of what improved.
Sound quality. I stream my own FLAC files, transcoded on the fly by Navidrome only when a slow connection demands it. No mystery about bitrates, no artificial tier locking lossless behind a higher price. It’s the best my music has ever sounded on the go.
Permanence. This is the big one. Nothing in my library can vanish because of a licensing dispute. The album that got pulled from Spotify because of some contract nobody explained to me? I own it. It’s on my drive. It will be there in ten years. My playlists are rows in a database I control. My play counts are mine. There is a deep, hard-to-overstate calm that comes from knowing your musical life can’t be revoked by an email.
Money to artists. Every purchase sends real money to the people who made the thing. I stopped being a rounding error in a payout formula and became a customer again. That reframing did more for my relationship with music than any algorithm ever did.
Curiosity came back. Because discovery now takes a little effort — reading a Bandcamp tag page, following a netlabel, digging through the Free Music Archive — I actually engage with new music instead of letting a queue autoplay past me. I’ve fallen down rabbit holes I’d forgotten how to fall down. Paradoxically, making discovery less frictionless made it more rewarding.
It’s mine. Every layer, from the tags to the server to the client, answers to me. When something annoys me, I fix it. That’s a feeling I’d forgotten was even available.
The honest downsides
I promised honesty, so here’s the other column, and it’s not short.
It is genuinely more effort. Spotify is a button. This is a hobby. I maintain a server, apply updates, run backups (a music library you don’t back up is a heartbreak waiting to happen — I sync mine to an external drive and an offsite copy), and occasionally debug why a client won’t connect. If you don’t enjoy this kind of tinkering, that maintenance will feel like a tax rather than a pastime. Be honest with yourself about which one you are.
Discovery is worse, in the narrow sense. ListenBrainz and manual digging are wonderful, but let’s not pretend they match the uncanny convenience of a billion-dollar recommendation engine trained on half the planet’s listening. If your primary use of streaming was “put on something good without thinking,” you will feel that loss. I decided the loss was the point. You might not.
No infinite catalog. I can’t think of an obscure song and have it playing in three seconds. If it’s not in my library, I have to go find it, buy it, and import it. That’s a real downgrade in raw convenience, and there are evenings I miss the firehose.
The upfront time cost is real. Between choosing the stack, learning beets and Picard, cleaning up my metadata, and setting up remote access, I spent a solid handful of evenings before the thing felt finished. It’s a project, not a purchase.
You are now the support department. When it breaks, there’s no one to call. The community forums are excellent and genuinely kind, but the buck stops with you.
Ownership versus convenience
So was it worth it? For me, unambiguously yes — but I’ve come to understand that this choice is really a referendum on a single tradeoff, and reasonable people land on different sides of it.
Streaming services sell convenience, and they are extraordinarily good at it. Infinite catalog, zero maintenance, brilliant recommendations, one flat fee, a button. What they can’t sell you, by their very nature, is ownership. The whole model depends on you never owning anything, because ownership is the thing that would let you leave.
What I built sells the opposite. It demands effort, it caps my catalog at whatever I’ve deliberately chosen, and it makes me my own IT department. In exchange, it gives me permanence, control, better fidelity, a direct line of money to the artists I love, and the quiet dignity of a musical life that belongs to me and can’t be repriced or revoked.
I don’t think everyone should do this. If you love the algorithm, if maintenance sounds like misery, if you value the firehose over the collection, then Spotify at $12.99 is probably a fair deal and you should enjoy it without guilt. This isn’t a moral crusade; it’s a preference, and mine happens to run toward ownership.
But I’d gently push back on the idea that this is only for hardcore hackers. The tools have gotten so good. A Raspberry Pi, a Docker command, Navidrome, an afternoon with beets, Tailscale on your phone, and a Bandcamp habit — that’s genuinely within reach of anyone comfortable following a good tutorial. The self-hosting community has done the hard work of making the hard work optional. You’re standing on the shoulders of a decade of stubborn people who refused to accept that music has to be a rental.
I still remember the moment it clicked emotionally. I was on a train, no signal, and I opened Amperfy and played an album I’d bought on Bandcamp the week before — a small record by a band with four thousand monthly listeners who got ten real dollars from me instead of a fraction of a cent. It sounded gorgeous. It was stored on a machine in my closet a hundred miles away, reachable over an encrypted tunnel that answered only to me. No email would ever take it away. No price hike would ever touch it. It was, in the fullest sense of a word I’d stopped being able to use about my music, mine.
I closed the app and watched the fields go by, and for the first time in years I felt like I owned my own soundtrack. That feeling was worth every evening I spent building it. Your mileage may vary — but I’d encourage you to at least find out.
Every tool named here is real and, as of 2026, actively maintained: Navidrome, Jellyfin, Funkwhale, and Airsonic-Advanced for servers; the OpenSubsonic API tying them to clients like Amperfy, Feishin, Supersonic, Symfonium, DSub, play:Sub, and substreamer; beets and MusicBrainz Picard for library management; Bandcamp, the Free Music Archive, and Creative Commons catalogs for ethical sourcing; and Tailscale or Caddy for remote access. The narrator is a composite; the path is real. If any of this stirred something, that stirring is the only part you need to bring yourself.

