https://github.com/darious/jamarr
Self-hosted music library scanner and UPnP controller with web and Android clients
https://github.com/darious/jamarr
android docker fastapi music postgresql self-hosted svelte upnp
Last synced: about 2 months ago
JSON representation
Self-hosted music library scanner and UPnP controller with web and Android clients
- Host: GitHub
- URL: https://github.com/darious/jamarr
- Owner: darious
- License: agpl-3.0
- Created: 2025-12-18T21:22:53.000Z (6 months ago)
- Default Branch: main
- Last Pushed: 2026-05-08T06:05:19.000Z (about 2 months ago)
- Last Synced: 2026-05-08T07:20:05.088Z (about 2 months ago)
- Topics: android, docker, fastapi, music, postgresql, self-hosted, svelte, upnp
- Language: Python
- Size: 3.82 MB
- Stars: 1
- Watchers: 0
- Forks: 0
- Open Issues: 11
-
Metadata Files:
- Readme: README.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
- Code of conduct: CODE_OF_CONDUCT.md
- Security: SECURITY.md
Awesome Lists containing this project
README
# Jamarr
**Self-hosted web-based music controller.**
Scan a local music library, enrich it with metadata from MusicBrainz and Spotify, then browse and play music through a fast web UI. Supports local playback and UPnP renderers (e.g., Naim Uniti Atom) with gapless queue management.
## Features
- **Library scanning** — fast tag-based scan with incremental updates and MusicBrainz ID extraction
- **Rich metadata** — artist bios, artwork, similar artists, top tracks, and external links
- **Local + UPnP playback** — local streaming and UPnP control (play/pause/seek/volume)
- **Gapless playback** — via UPnP SetNextAVTransportURI queue management
- **Instant search** — across artists, albums, and tracks
- **History + Last.fm** — local playback history with matched Last.fm scrobbles
- **Recommendations** — artist/album/track recommendations from listening history
- **Playlists** — create and manage playlists with ordering support
- **Modern UI** — responsive SvelteKit interface with renderer switching
## Quick Start
### 1. Configure
```bash
cp .env.example .env
```
Edit `.env` and set the required values:
| Variable | Description |
|:---|:---|
| `HOST_IP` | Your server's LAN IP (auto-detected by `deploy.sh` if left unset) |
| `MUSIC_NFS_ADDR` | NFS server address hosting your music library |
| `MUSIC_NFS_PATH` | NFS export path on the server |
| `DB_DATA_PATH` | Host directory for PostgreSQL data |
| `CACHE_PATH` | Host directory for Jamarr cache |
| `JWT_SECRET_KEY` | Generate with `python -c "import secrets; print(secrets.token_urlsafe(32))"` |
| `SPOTIFY_CLIENT_ID` / `SPOTIFY_CLIENT_SECRET` | Spotify API credentials (for metadata enrichment) |
| `LASTFM_API_KEY` / `LASTFM_SHARED_SECRET` | Last.fm API credentials (for scrobbling) |
Optional API keys for additional metadata sources: `QOBUZ_*`, `TIDAL_*`, `FANARTTV_API_KEY`.
Non-secret app config (MusicBrainz URL, logging, concurrency) lives in `config.yaml`.
### 2. Deploy
```bash
./deploy.sh
```
This pulls the latest image, backs up the database, runs migrations, and restarts the stack. The container uses `network_mode: "host"` for UPnP device discovery.
### 3. Scan your library
```bash
docker compose run --rm jamarr uv run python -m app.scanner.cli scan
docker compose run --rm jamarr uv run python -m app.scanner.cli metadata
```
See [Scanner CLI](docs/scanner.md) for full command reference.
### 4. Open the UI
`http://your-server-ip:8111`
## Documentation
| Document | Description |
|:---|:---|
| [Architecture & Outline](docs/outline.md) | System overview and design |
| [Database Schema](docs/DATABASE_SCHEMA.md) | Tables, views, and indexes |
| [Scanner CLI](docs/scanner.md) | Library scanning and metadata enrichment |
| [API](docs/api.md) | API endpoints |
| [Auth](docs/auth.md) | Authentication and JWT |
| [Dev Mode](docs/DEV_MODE.md) | Development with hot-reload |
| [Contributing](CONTRIBUTING.md) | Development setup, tests, linting |
## License
Jamarr is licensed under the GNU Affero General Public License v3.0 only (`AGPL-3.0-only`). See [LICENSE](LICENSE).
Third-party dependencies, logos, service names, and trademarks remain under their own licenses. See [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md).