Enhance README with system overview and setup instructions

Added detailed documentation about the music discovery and streaming system, including components, folder structure, configuration files, automation scripts, and tips for users.
This commit is contained in:
Quinta
2026-04-28 20:05:32 +02:00
committed by GitHub
parent d7d988053c
commit 7501b46c15
+267
View File
@@ -1,2 +1,269 @@
# Ainulindale
A fully self-hosted, automated music discovery and streaming system. No Spotify. No YouTube Music. No ads. Just your music, your server, your rules.
---
## What This Stack Does
- **Streams** your music library to any device via a Spotify-like interface
- **Automatically discovers** new music weekly based on your listening habits
- **Downloads** discovered tracks at high quality (FLAC/WAV preferred, 320kbps minimum) from the Soulseek network
- **Scrobbles** everything you listen to Last.fm and ListenBrainz
- **Routes all P2P traffic through a VPN** so your real IP is never exposed
---
## Components
| Component | Role |
|---|---|
| **Navidrome** | Music server — indexes your library, streams to clients |
| **Substreamer** | Mobile app (iOS/Android) — plays music from Navidrome |
| **Pangolin** | Reverse proxy — exposes Navidrome securely to the internet |
| **Gluetun** | VPN gateway container — all Soulseek traffic exits via ProtonVPN |
| **slskd** | Soulseek client — searches and downloads music from the P2P network |
| **Explo** | Discovery engine — connects ListenBrainz recommendations to slskd |
| **ListenBrainz** | Open-source scrobbler + recommendation engine |
| **Last.fm** | Secondary scrobbler for stats and social features |
---
## Folder Structure
```
/mnt/user/appdata/
├── gluetun/ ← VPN state (auto-populated)
├── slskd/
│ └── slskd.yml ← slskd config
└── explo/
├── .env ← Explo config
└── docker-compose.yml ← Full stack compose file
/mnt/user/data/media/music/
├── incomplete/ ← In-progress downloads (Navidrome ignores these)
├── explo/ ← Explo-managed discovery downloads
└── (your library)/ ← Everything else
```
---
## docker-compose.yml
```yaml
services:
gluetun:
image: qmcgaw/gluetun:latest
container_name: gluetun
cap_add:
- NET_ADMIN
devices:
- /dev/net/tun:/dev/net/tun
environment:
- VPN_SERVICE_PROVIDER=protonvpn
- VPN_TYPE=wireguard
- WIREGUARD_PRIVATE_KEY=YOUR_PRIVATE_KEY_HERE
- WIREGUARD_ADDRESSES=10.2.0.2/32
- SERVER_COUNTRIES=Switzerland
- TZ=Europe/Zurich
ports:
- 5030:5030
volumes:
- /mnt/user/appdata/gluetun:/gluetun
restart: unless-stopped
slskd:
image: slskd/slskd:latest
container_name: slskd
network_mode: "service:gluetun"
depends_on:
gluetun:
condition: service_healthy
environment:
- SLSKD_REMOTE_CONFIGURATION=true
volumes:
- /mnt/user/appdata/slskd:/app
- /mnt/user/data/media/music:/downloads
- /mnt/user/data/media/music:/music:ro
restart: unless-stopped
explo-weekly:
image: ghcr.io/lumepart/explo:latest
container_name: explo-weekly
environment:
- EXECUTE_ON_START=true
- WEEKLY_EXPLORATION_FLAGS=--playlist=weekly-exploration --persist
volumes:
- /mnt/user/appdata/explo/.env:/opt/explo/.env
- /mnt/user/data/media/music/explo:/data
- /mnt/user/data/media/music:/slskd
restart: "no"
explo-daily:
image: ghcr.io/lumepart/explo:latest
container_name: explo-daily
environment:
- EXECUTE_ON_START=true
- DAILY_JAMS_FLAGS=--playlist=daily-jams --download-mode=skip
volumes:
- /mnt/user/appdata/explo/.env:/opt/explo/.env
- /mnt/user/data/media/music/explo:/data
- /mnt/user/data/media/music:/slskd
restart: "no"
```
---
## Explo .env
```env
# --- Discovery ---
DISCOVERY_SERVICE=listenbrainz
LISTENBRAINZ_USER=your_listenbrainz_username
LISTENBRAINZ_DISCOVERY=playlist
# --- Navidrome (Subsonic API) ---
EXPLO_SYSTEM=subsonic
SYSTEM_URL=http://192.168.1.x:4533
SYSTEM_USERNAME=your_navidrome_username
SYSTEM_PASSWORD=your_navidrome_password
# --- Downloaders (slskd first, YouTube fallback) ---
DOWNLOAD_SERVICES=slskd,youtube
TRACK_EXTENSION=mp3
# --- slskd ---
SLSKD_URL=http://slskd:5030
SLSKD_API_KEY=your_slskd_api_key
MIGRATE_DOWNLOADS=true
RENAME_TRACK=true
# --- Quality gates (FLAC/WAV preferred, 320kbps minimum) ---
EXTENSIONS=flac,wav,mp3
MIN_BITRATE=320
MIN_BIT_DEPTH=16
# --- YouTube fallback (optional) ---
YOUTUBE_API_KEY=your_youtube_api_key
# --- Misc ---
SLEEP=2
LOG_LEVEL=INFO
```
---
## slskd.yml
```yaml
soulseek:
username: your_soulseek_username
password: your_soulseek_password
web:
authentication:
username: your_chosen_web_username
password: your_chosen_web_password
api_keys:
explo_key:
key: your_api_key_minimum_16_chars_long
role: readwrite
cidr: 0.0.0.0/0,::/0
directories:
incomplete: /downloads/incomplete
downloads: /downloads
transfers:
download:
slots: 50
upload:
slots: 20
shares:
directories:
- /music
```
---
## Navidrome (Unraid Community Apps)
Navidrome is installed via Unraid's Community Apps store. Add these extra environment variables in the container template:
| Variable | Value |
|---|---|
| `ND_LASTFM_APIKEY` | your Last.fm API key |
| `ND_LASTFM_SECRET` | your Last.fm shared secret |
| `ND_LASTFM_ENABLED` | `true` |
| `ND_SCANSCHEDULE` | `1m` |
Last.fm API credentials: [last.fm/api/account/create](https://www.last.fm/api/account/create)
---
## Automation — Unraid User Scripts
Install the **User Scripts** plugin from Community Apps, then add two scripts:
### Weekly Exploration (every Tuesday at 00:15)
Cron: `15 0 * * 2`
```bash
#!/bin/bash
docker compose -f /mnt/user/appdata/explo/docker-compose.yml up explo-weekly
```
### Daily Jams (every day at 00:15)
Cron: `15 0 * * *`
```bash
#!/bin/bash
docker compose -f /mnt/user/appdata/explo/docker-compose.yml up explo-daily
```
---
## How Discovery Works
```
You listen in Substreamer
↓
Navidrome scrobbles to Last.fm + ListenBrainz
↓
ListenBrainz builds your taste profile over time
↓
Every Monday night: ListenBrainz generates Weekly Exploration playlist
↓
Tuesday 00:15: Explo pulls recommendations
↓
slskd searches Soulseek network (behind ProtonVPN)
↓
Downloads FLAC/WAV/320kbps+ to /mnt/user/data/media/music
↓
Navidrome scans every 1 minute → appears in Substreamer
↓
You discover new music 🎵
```
---
## Tips
- **ListenBrainz needs time** — it takes a few weeks of scrobbling before Weekly Exploration playlists are generated. Speed this up by importing your Google Takeout YouTube Music watch history via [ytm-extractor](https://community.metabrainz.org/t/ytm-extractor-import-youtube-music-listens-to-listenbrainz/707619).
- **Manual downloads** — search for any artist or album directly in the slskd web UI at `http://your-nas-ip:5030`. Downloads land straight in your Navidrome library.
- **Playlist import** — use [Soundiiz](https://soundiiz.com) to transfer playlists from YouTube Music/Spotify directly into Navidrome. Tracks already in your library get matched automatically.
- **Quality** — slskd is tried first for every download. YouTube is only used as a last resort fallback for tracks not found on Soulseek.
- **Sharing** — slskd shares your music library back to the Soulseek network. The more you share, the better your download priority from other peers.
- **ProtonVPN** — the WireGuard private key in Gluetun pins you to a specific server. Make sure to use a P2P-capable server when generating your WireGuard config on ProtonVPN's site.
---
## Prerequisites
- Unraid NAS (or any Linux server with Docker)
- ProtonVPN account (paid, for P2P/WireGuard support)
- Soulseek account — free at [slsknet.org](https://www.slsknet.org)
- ListenBrainz account — free at [listenbrainz.org](https://listenbrainz.org)
- Last.fm account — free at [last.fm](https://www.last.fm)
- Last.fm API key — free at [last.fm/api](https://www.last.fm/api/account/create)
- Substreamer app on your phone
- Pangolin or any reverse proxy for external access