# Contributing and self-hosting ## Requirements - Go 1.27 - [Postgres](https://www.postgresql.org) - [Qdrant](https://qdrant.tech) ## Running the backend ```console $ just up ``` This starts Postgres and Qdrant on Docker Compose, builds the backend, and runs it listening on `127.0.0.1:8080`. To backfill into the database once, use `docker compose run --rm -e BUBBLEMIX_JETSTREAM_API_KEY= bubblemix backfill` (hosts that charge for archive replay require the key). Every `BUBBLEMIX_REBUILD_INTERVAL` the backend recomputes the co-listen graph from all stored scrobbles and syncs one sparse vector per song (its normalized co-listen profile) into Qdrant, which serves the related-song queries with server-side MMR re-ranking. ## Environment | Variable | Default | Purpose | | --- | --- | --- | | `BUBBLEMIX_LISTEN_ADDR` | `:8080` | Listen address | | `BUBBLEMIX_DATABASE_URL` | `postgres://bubblemix:bubblemix@127.0.0.1:5432/bubblemix` | Postgres connection string | | `BUBBLEMIX_QDRANT_URL` | `http://127.0.0.1:6334` | Qdrant gRPC endpoint | | `BUBBLEMIX_COLLECTION` | `bubblemix` | Qdrant collection | | `BUBBLEMIX_JETSTREAM_URL` | `wss://jetstream.us-west.bsky.network` | Jetstream host for the live tail | | `BUBBLEMIX_JETSTREAM_BACKFILL_URL` | same as live | Jetstream host for the backfill | | `BUBBLEMIX_API_TOKEN` | — | When set, requests need `Authorization: Bearer ` | | `BUBBLEMIX_REBUILD_INTERVAL` | `8h` | Interval between graph rebuilds | | `BUBBLEMIX_MAX_SONGS_PER_DID` | `512` | Songs per listener considered when computing co-listen edges | ## API | Route | Returns | | --- | --- | | `GET /health` | `200` while the process runs | | `GET /v1/related` | Songs people who listen to a song also listen to, re-ranked with MMR | `/v1/related` takes `artist` and `title` (or `mbid` and `isrc`), optional `album`, `count` (1–128, default 32), and `diversity` (0–1, default 0.8: how much results favor variety over pure similarity): ```console $ curl "localhost:8080/v1/related?artist=Chico%20Science&title=Da%20Lama%20ao%20Caos&count=3" ``` ```json { "song": {"title": "Da Lama ao Caos", "artist": "Chico Science", "score": 0}, "results": [ {"title": "A Cidade", "artist": "Chico Science", "score": 0.83}, {"title": "O Canto da Cidade", "artist": "Daniela Mercury", "score": 0.71} ], "count": 2 } ``` ## Reference implementations * Docker Compose: the `compose.yml` works for production, but you might want to double-check how you want to persist data on your volumes (e.g. point them to a directory to make it easy to back up). * Kubernetes: you can copy what I have at [my home lab](https://tangled.org/cuducos.me/pop-zero/tree/main/apps/navidrome).