3c77066beb7b413cf1117a4955972006d1d3ed5d
HomelabToolkit
A self-hosted control room for your media stack. HomelabToolkit pairs an Emby artwork toolkit with a Navidrome music-library manager behind one beautiful React UI, served by a FastAPI backend.
Categories
Emby
- Thumbnail Generator — composite landscape thumbnails from posters, logos and backdrops (subject-aware), then push them back to Emby as custom Thumb images.
- Collection Art — design Thumb/Primary cover artwork for your collections.
- Airing & New Seasons — track currently-airing series and stamp "New Season" artwork on eligible premieres.
- Bulk Assign — generate and apply thumbnails across the whole library, plus per-studio artwork resets.
- User Favorites — browse collections with per-user watched status, prune watched items, and top up with recommendations (dry-run by default).
- Weekly Preroll Rotation — schedule your Emby preroll folder to rotate once per week from the Settings page, with a manual "Run now" action for testing.
Navidrome
- Music Library — browse artists and albums over the Subsonic API.
- Cover Manager — the former
music-covers.pyscript, now a web tool: scan the library, normalize album folders, rename tracks, remove stray files, and fetch missing covers/lyrics. Runs in dry-run mode by default — nothing on disk changes until you explicitly switch to apply mode.
Architecture
- Backend: Python, FastAPI, Pillow, rembg (U2-Net). API-only; serves the built
SPA and owns every
/api/*route. - Frontend: React + TypeScript + Vite (
frontend/), built tofrontend/dist. - Music tooling: mutagen + musicbrainzngs + Cover Art Archive + LRCLIB.
Configuration (environment variables)
| Variable | Purpose |
|---|---|
EMBY_URL |
Emby server URL |
EMBY_API_KEY |
Emby API key |
NAVIDROME_URL |
Navidrome server URL (Subsonic API) |
NAVIDROME_USER |
Navidrome username |
NAVIDROME_PASSWORD |
Navidrome password |
MUSIC_ROOT |
Path to the music library for the Cover Manager |
PREROLL_ENABLED |
Enable the weekly preroll task by default |
PREROLL_ACTIVE_DIR / PREROLL_INACTIVE_DIR |
Mounted preroll folders to rotate between |
PREROLL_STATE_FILE |
Where weekly rotation state is stored |
PREROLL_WEEKDAY / PREROLL_TIME |
Default weekly schedule for the preroll task |
TMDB_BEARER_TOKEN / TMDB_API_KEY |
Optional artwork providers |
GOOGLE_CUSTOM_SEARCH_API_KEY / ..._ENGINE_ID |
Optional artwork search |
Run with Docker (recommended)
- Edit
docker-compose.ymlwith your Emby/Navidrome details and mount your music share to matchMUSIC_ROOT. If you want weekly preroll rotation, also mount the active/inactive preroll folders and either set thePREROLL_*defaults there or configure the task in the app's Settings page. - Build and run:
The image builds the React SPA in a Node stage, then serves it from FastAPI.
docker compose up -d --build - Open
http://localhost:8500.
Local development
Backend:
pip install -r requirements.txt
python app.py # http://localhost:8500
Frontend (hot reload, proxies /api to :8500):
cd frontend
npm install
npm run dev # http://localhost:5173
Production build of the SPA (served by FastAPI):
cd frontend && npm run build
Deploy to a NAS
deploy.ps1 syncs the project (including the frontend/ source) over SSH and runs
docker compose build && up -d remotely. The frontend is built inside the image:
.\deploy.ps1 -NasHost MATT-NAS -NasUser ssh
Languages
Python
37.5%
TypeScript
20.3%
HTML
18.7%
Svelte
11.7%
JavaScript
6.5%
Other
5.3%