Self-hosted music server with a web player. Music, radio, and podcasts.
(frontend)
(backend)
- Stream your own music library (FLAC, MP3, and more, with Opus transcoding)
- Search across tracks, albums, and artists
- Playlists, liked tracks, and play queue with repeat modes
- Auto-generated playlists built from audio analysis (Essentia) and listening history
- Artist radio and curated internet radio stations (skip-aware, tunable station pools)
- Crossfade between tracks and replay gain volume normalization
- Podcasts with saved progress and continue listening
- Synced lyrics via LRCLIB
- Cover art and artist images via MusicBrainz and Wikidata (no API keys)
- Year end review
- Persistent login, sign in once per device
- Admin dashboard with activity logs and library management
- PHP 8.4 on Echo (custom framework, included in this repo)
- MariaDB, Redis, nginx, Docker Compose
- Twig and HTMX on the frontend
- Docker and Docker Compose
- A music library on disk
git clone https://github.com/whleucka/soprano.git
cd soprano
cp .env.example .env- Edit
.env, setMUSIC_DIRto your music library path - Start the dev stack:
./bin/dev up -d --build
./echo migrate:run
./echo soprano:sync- Open
http://localhost:8083and register an account
- Set
PROD_HOSTNAME,BUILD_MODE=prod, andAPP_DEBUG=falsein.env - Traefik handles TLS via Let's Encrypt
./bin/prod up -d --buildCommands run inside the php container via ./bin/php:
./echo soprano:sync # sync tracks, artists, albums, covers
./echo soprano:lyrics # backfill lyrics from LRCLIB
./echo soprano:artist-images # backfill artist images
./echo soprano:transcode # warm the Opus transcode cache
./echo soprano:duplicates # find and remove duplicate tracks
./echo soprano:trash # list or purge files trashed by soprano:duplicates
./echo soprano:stations # report station pool sizes and percentile thresholds
./echo migrate:run # run pending migrationsRun ./echo list for everything else.
composer testMIT