diff --git a/README.md b/README.md index 9fb46ebe..914a6ef9 100644 --- a/README.md +++ b/README.md @@ -1,44 +1,99 @@ # Minstrel -Self-hosted music server with OpenSubsonic compatibility plus an extended API for server-side smart shuffle, a dual-like model (general + contextual), session-aware radio, ListenBrainz scrobble/similarity, and Lidarr integration. Go + Postgres, packaged as a Docker container. +A self-hosted music server that thinks for you. Smart shuffle, contextual likes, ListenBrainz-aware radio, and Lidarr automation — server-side, so every client (web, mobile, Subsonic third-party) gets the same intelligence. > State and intelligence belong on the server, not the client. + + +## Highlights + +- **OpenSubsonic-compatible.** Existing Subsonic clients (DSub, Symfonium, play:Sub, etc.) connect with no special configuration. +- **Server-side smart shuffle.** Track-similarity vectors, dual-like model (general + contextual), and session memory keep mixes coherent across devices. +- **ListenBrainz radio.** Session-aware "more like this" pulls from ListenBrainz similarity data, not a static genre tag. +- **Lidarr integration.** Triggered scans, request-driven album imports, and a quarantine flow when something doesn't fit. +- **Built-in web SPA.** Full-feature library, search, queue, playlists, and admin — no separate frontend container to deploy. +- **Flutter mobile client in flight.** Tracking issue [#356](https://git.fabledsword.com/bvandeusen/minstrel/issues/356). + +## Quickstart + +```yaml +# compose.yaml +services: + minstrel: + image: git.fabledsword.com/bvandeusen/minstrel:v1.0.0 + ports: ['4533:4533'] + volumes: + - ./music:/music:ro + - minstrel-data:/data + environment: + SMARTMUSIC_DATABASE_URL: postgres://minstrel:minstrel@db:5432/minstrel?sslmode=disable + SMARTMUSIC_LIBRARY_ROOT: /music + depends_on: [db] + + db: + image: postgres:17 + environment: + POSTGRES_USER: minstrel + POSTGRES_PASSWORD: minstrel + POSTGRES_DB: minstrel + volumes: [pgdata:/var/lib/postgresql/data] + +volumes: + minstrel-data: + pgdata: +``` + +```bash +docker compose up -d +``` + +Open `http://localhost:4533` and complete the first-run admin setup. + +For the full configuration surface, see [`config.example.yaml`](./config.example.yaml). + +## Configuration + +Most operators only need the env vars in the quickstart above. A few extras worth knowing: + +- `SMARTMUSIC_BRANDING_APP_NAME` — rename the instance ("Family Jukebox", "Office Music"). Surfaces in the header, browser tab, and OG share previews. +- `SMARTMUSIC_STORAGE_DATA_DIR` — defaults to `./data`. Holds playlist cover collages and other generated artefacts. +- `SMARTMUSIC_LISTENBRAINZ_TOKEN` — enables ListenBrainz scrobble + similarity. Per-user tokens override the server default in Settings. +- `SMARTMUSIC_LIDARR_URL` / `SMARTMUSIC_LIDARR_API_KEY` — Lidarr integration. Configure once at the server level; per-user request flows are exposed in the admin UI. + +Every yaml key has an equivalent env var (`SMARTMUSIC_
_`). See `config.example.yaml` for the full list. + +## Updating + +- `:main` — rolling, follows the dev branch's tested tip. Recommended only for the operator who's running an upstream-watching deployment. +- `:v1.0.x` — pinned releases. Recommended default. Database migrations run automatically at startup; rollbacks require restoring a Postgres dump. + ## Specs -Authoritative v1 scope lives under [`docs/`](./docs): +Authoritative scope lives under [`docs/`](./docs): - [Server spec](./docs/smart-music-server-spec.md) — current implementation focus. -- [Client spec](./docs/smart-music-client-spec.md) — Flutter companion app; work starts once the server reaches its Subsonic-compatible baseline. - -## Development workflow - -- Day-to-day work happens on the `dev` branch (or feature branches merged into `dev`). -- `main` is **protected** — changes land only via pull request from `dev`. -- Production builds are cut by tagging a release (`v*`) off `main`. - -## CI / container image - -Forgejo Actions handles: - -- Tests on push to `dev` and on PRs into `main`. -- Container image build + push to the Forgejo registry on merge to `main` (`:main`) and on `v*` tags (`:`). - -Task and milestone tracking: Fable (`Minstrel` project, id 12). +- [Client spec](./docs/smart-music-client-spec.md) — Flutter companion app. ## Development -Minstrel has two concurrent dev processes: +Two concurrent dev processes: -1. **Backend:** `docker compose up` — starts Postgres and Minstrel on `:4533`. -2. **Frontend:** `cd web && npm install && npm run dev` — Vite dev server on `:5173` with HMR. - -The Vite dev server proxies `/api/*` and `/rest/*` to the backend on `:4533`, -so session cookies work correctly when the SPA is loaded from the Vite origin. +1. **Backend:** `docker compose up` — Postgres + Minstrel on `:4533`. +2. **Frontend:** `cd web && npm install && npm run dev` — Vite dev server on `:5173` with HMR. The Vite server proxies `/api/*` and `/rest/*` to `:4533` so session cookies work. ### Production build -`docker build -t minstrel .` runs the SvelteKit build inside a `node` stage, -copies the output into the `golang` stage, and `//go:embed`s it into the -final binary. The resulting container serves the SPA from `/` alongside the -API surfaces. No separate static-file server is required. +`docker build -t minstrel .` runs the SvelteKit build inside a `node` stage, copies the output into the `golang` stage, and `//go:embed`s it into the final binary. The container serves the SPA from `/` alongside the API surfaces; no separate static-file server is required. + +### Branches + +- Day-to-day work happens on `dev` (or feature branches merged into `dev`). +- `main` is **protected** — changes land via PR from `dev`. +- Releases are cut by tagging `v*` off `main`; the release workflow builds and pushes the container image to the Forgejo registry. + +Task and milestone tracking: Fable (`Minstrel` project, id 12). + +## License + +See [LICENSE](./LICENSE).