# Tired of Subscriptions, So I Built My Own Server

> Source: <https://dev.to/ashusosuke/tired-of-subscriptions-so-i-built-my-own-server-14m>
> Published: 2026-08-18 07:09:56+00:00

Another month, another stack of bills for a music app, a movie app, cloud storage — all for things I could technically host myself. So I did.

That question turned into a home server on a repurposed laptop, a full Docker stack, and a Python pipeline that's had four separate fights with YouTube's anti-bot systems in a single week. And once I had a server I actually controlled, the ideas didn't stop — a personal webpage, automations, my own music/movie player, an AI agent to manage it all. Here's how it came together.

The setup

A 16GB/i5 laptop I wasn't using became a Debian 13 VM (headless, VirtualBox), reachable from anywhere via Tailscale. One Docker stack runs on top:

Jellyfin — my own Netflix

Navidrome — my own Spotify

Samba — a network drive from any device

Portainer / Homepage — management + dashboard

PostgreSQL — shared DB engine

Pi-hole — network-wide ad block (in progress)

No more monthly bills for things a spare laptop can do for free.

The hard part: filling it with music

Hosting a Spotify clone is easy. Filling it with your actual library isn't. Spotify's Feb 2026 API change blocked the clean OAuth route, so I improvised: export playlists as CSVs (via Exportify), then built MusicVault — a pipeline that parses them, finds each track on YouTube, downloads it, and auto-generates playlists Navidrome can serve.

5,748 tracks. 97 playlists. Starting from zero.

Four fights with YouTube

Storage — FLAC files were about to blow past my 200GB disk. Switched everything to MP3.

Silent failures — my own script was hiding the real error. Fixed the logging first, which revealed YouTube's bot-check. Fixed with browser cookies.

"Format not available" — YouTube now requires solving a JS challenge for some streams. Installed a JS runtime + solver, and caught a sneaky bug where ~ silently failed inside a command flag.

Mass 403 errors — a live, actively-evolving yt-dlp issue other users were hitting that same week. Fixed by forcing a different YouTube client. Even the fix had a gotcha: a tabs-vs-spaces mismatch silently blocked my first patch attempt.

Four unrelated failure modes, back to back — each one real debugging, not copy-paste.

What's next

A personal webpage, hosted off the server

Automations — disk monitoring, auto-cleanup, alerts when things break

A custom-built music/movie player instead of default UIs

An AI agent layer to manage the server in plain language

Eventually: Nextcloud, Gitea, self-hosted photo backup

What started as "stop paying for four apps" turned into a home-lab I'm still adding to every week — and that's the part I like most.
