Soulbeet
Automated music downloader and manager integrating Slskd and Beets.
Install / Use
/learn @terry90/SoulbeetREADME
Soulbeet
Soulbeet is a self-hosted music downloader, library manager, and discovery engine. Search for music, download it from Soulseek, auto-tag with beets, and get weekly discovery playlists pushed to your Navidrome server based on your Last.fm and ListenBrainz listening history.
Screenshots: here
Features
- Search & Download: Find albums and tracks via MusicBrainz or Last.fm, then download from Soulseek in one click. Beets handles tagging and organization.
- Music Discovery: Get personalized recommendations based on your scrobble history. Soulbeet analyzes your listening across Last.fm and ListenBrainz, finds new music through track similarity, artist exploration, collaborative filtering, and genre discovery, then downloads the best candidates and creates Navidrome playlists for you.
- Three Discovery Profiles: Conservative (stay close to what you know), Balanced, or Adventurous (push into unfamiliar territory). Run one or all three in parallel, each with its own playlist.
- Rate & Keep: Listen to discovery tracks in Navidrome. Rate them: 3+ stars promotes to your library, 1 star deletes it. Unrated tracks expire after a configurable lifetime and get replaced with a fresh batch.
- Multi-user: Private or shared folders for families and friend groups. Each user has their own discovery profiles, scrobble credentials, and preferences. Shared folders respect everyone's ratings before auto-deleting.
- Multiple Metadata Providers: MusicBrainz (better for albums) or Last.fm (better for single tracks), selectable per user.
How It Works
- Soulbeet Web -- the main interface (Dioxus fullstack app)
- Slskd -- Soulseek P2P client, handles the actual downloads
- Beets -- tags, organizes, and moves files into your library
- Navidrome -- streams your music, hosts discovery playlists, provides rating feedback
- Last.fm / ListenBrainz -- scrobble services that feed the recommendation engine
- SQLite -- stores everything (users, folders, candidates, engine reports, profiles)
Self-Hosting with Docker
The recommended way to run Soulbeet is via Docker Compose. This ensures all dependencies (like beets and python) are correctly set up.
Compatibility: The Docker image supports both AMD64 and ARM64 architectures.
Prerequisites
- Docker & Docker Compose (or podman-compose)
Quick Start
- Create a
docker-compose.ymlfile:
services:
soulbeet:
image: docker.io/docccccc/soulbeet:latest
restart: unless-stopped
ports:
- 9765:9765
environment:
- DATABASE_URL=sqlite:/data/soulbeet.db
- DOWNLOAD_PATH=/downloads
- SECRET_KEY=change-me-in-production
- NAVIDROME_URL=http://navidrome:4533
# Optional
- BEETS_CONFIG=/config/config.yaml
volumes:
- ./data:/data
- /path/to/slskd/downloads:/downloads
- /path/to/music:/music
depends_on:
- slskd
- navidrome
navidrome:
image: deluan/navidrome:latest
ports:
- "4533:4533"
environment:
- ND_MUSICFOLDER=/music
volumes:
- ./navidrome-data:/data
- /path/to/music:/music
slskd:
image: slskd/slskd
environment:
- SLSKD_REMOTE_CONFIGURATION=true
volumes:
- ./slskd-config:/app/slskd.conf.d
- /path/to/slskd/downloads:/app/downloads
ports:
- "5030:5030"
-
Important: The
/downloadsvolume must match betweenslskdandsoulbeetso Soulbeet can see the filesslskddownloaded. The/musicvolume must match betweensoulbeetandnavidromeso Navidrome can see the organized library. -
Run:
docker-compose up -d
Initial Setup
- Open
http://localhost:9765 - Log in -- Soulbeet authenticates against your Navidrome server, so use your Navidrome credentials.
- Go to Settings.
- Configure slskd connection (Settings > Config): Add your slskd URL (e.g.,
http://slskd:5030) and API key. Get your API key from slskd config file or add one. - Add Music Folders (Settings > Library): Add the paths where you want your music stored (e.g.,
/music/Person1,/music/Person2,/music/Shared). These must be paths accessible inside the Docker container. - Set up Discovery (Settings > Library): Add your Last.fm API key and/or ListenBrainz token. Enable discovery on a folder, pick your profiles, and hit Generate.
- Enable scrobbling in Navidrome: Go to your Navidrome personal settings and enable Last.fm/ListenBrainz scrobbling. The more listening history these services have, the better the recommendations get.
Configuration
Environment Variables
| Variable | Description | Default |
|----------|-------------|---------|
| DATABASE_URL | Connection string for SQLite | sqlite:soulbeet.db |
| DOWNLOAD_PATH | Path where slskd saves downloads | /downloads |
| SECRET_KEY | Encryption key for tokens and credentials | |
| NAVIDROME_URL | Your Navidrome server URL | |
| BEETS_CONFIG | Path to custom beets config file | beets_config.yaml |
| BEETS_ALBUM_MODE | Enable album import mode (see below) | false |
Note: slskd URL and API key are configured through the web UI (Settings > Config) and stored in the database. Scrobble credentials (Last.fm API key, ListenBrainz token) are configured per-user in Settings > Library.
Beets Configuration
Soulbeet uses beets to import music. You can mount a custom config.yaml to /config/config.yaml (or wherever you point BEETS_CONFIG to) to customize how beets behaves (plugins, naming formats, etc.).
Default beet import flags used:
-q: Quiet mode (no user interaction)-s: Singleton mode (Default behavior unlessBEETS_ALBUM_MODEis set)-l [library_path]: Library database path (per-folder)-d [target_path]: Import to the specific folder selected in the web UI.
Library Management
Important: Each music folder you configure in Soulbeet has its own beets database (.beets_library.db) stored at the root of that folder. This enables:
- Per-folder duplicate detection
- Independent library management for each user/folder
- Cross-library duplicate detection
Interacting with Your Library
Each user can have multiple libraries. Each library is a folder that contains music files and a .beets_library.db file. This database is used to avoid duplicate tracks within the same library.
Since we use different databases, we can't directly compare tracks across libraries. However, we can use the beets CLI to interact with each library individually. This way you can add tracks outside of Soulbeet but keep them in sync with your library.
To manually interact with a library (list tracks, modify tags, remove items, etc.), use the beet CLI with the -l flag pointing to the folder's database:
# List all tracks in a library
beet -l /music/Person1/.beets_library.db ls
If using Docker, run these commands inside the container:
docker exec -it <container_name> beet -l /music/Person1/.beets_library.db ls
For more beets commands, see the beets documentation.
Album Mode (BEETS_ALBUM_MODE)
By setting BEETS_ALBUM_MODE=true, Soulbeet will attempt to group downloaded files by their parent directory and import them as an album instead of singletons.
This flag is only needed when you want album tags on your tracks. E.g: albumartist mb_albumid and so on..
Important for Album Mode:
Since beets is run in quiet mode (-q), it will skip any imports that require user intervention (e.g., if the metadata doesn't match confidently). To ensure partial albums or less popular releases are imported correctly, you must configure your beets_config.yaml to be more permissive.
Recommended additions to your beets_config.yaml for Album Mode:
import:
# quiet_fallback: asis # Optional: If no strong match, import with existing tags instead of skipping
timid: no
match:
strong_rec_thresh: 0.10 # Lower threshold to accept less confident matches
max_rec:
missing_tracks: strong
unmatched_tracks: strong
distance_weights:
missing_tracks: 0.1 # Reduce weight (I think default is 0.9) to penalize less for missing tracks, improving the overall score.
# unmatched_tracks: 0.2 # Optional: Similar for extra tracks.
Note: Tweaking strong_rec_thresh and other matching parameters increases the risk of incorrect tags, but is necessary for fully automated imports of obscure or partial albums.
Discovery Setup
Discovery generates personalized playlists from your scrobble history and pushes them to Navidrome. Here's how to set it up.
Navidrome Configuration
-
Enable ReportRealPath for the Soulbeet player. Go to your Navidrome instance > Settings > Players (e.g.
https://your-navidrome/app/#/player), find the Soulbeet player entry, and enable "Report Real Path". Without this, rating sync and auto-delete cannot resolve file paths. -
Your Soulbeet folder paths must point to the same physical directories
