Sign inSign up

gatoserio/song-randomizer

By gatoserio

•Updated 3 months ago

Spotify playlist roulette — one shared queue, no repeats.

Image
0

604

gatoserio/song-randomizer repository overview

⁠Spotify Roulette

A self-hosted PWA that picks a random song from a Spotify playlist with a decelerating roulette wheel of album covers and a synced tick sound. Built for a small party of players who take turns spinning — the app guarantees no player hears the same song twice.

  • Stack: Fastify + TypeScript backend, React + Vite frontend, single Docker image.
  • State: embedded SQLite in a Docker volume (/data/roulette.db) via Node's built-in node:sqlite. No database server.
  • Admin: optional /admin panel (set ADMIN_PASSWORD) for player management, resets, and per-player spin history.
  • Auth: Spotify PKCE, server-side only. Tokens never reach the browser.
  • Playback: Spotify Connect (host account must be Premium), deep-link fallback if no device is active.

Source: github.com/PauloJf/song-randomizer⁠.

⁠Run

services:
  app:
    image: <your-dockerhub-user>/song-randomizer:latest
    restart: unless-stopped
    ports:
      - "3000:3000"
    environment:
      SPOTIFY_CLIENT_ID: ${SPOTIFY_CLIENT_ID}
      PLAYLIST_ID: ${PLAYLIST_ID}
      PLAYERS: Alice,Bob,Carol,Dave
      BASE_URL: https://your-domain.example
      PORT: 3000
      COOKIE_SECRET: ${COOKIE_SECRET}
    volumes:
      - roulette-state:/data

volumes:
  roulette-state:
⁠docker run
docker run -d --name spotify-roulette \
  -p 3000:3000 \
  -v roulette-state:/data \
  -e SPOTIFY_CLIENT_ID=your_client_id \
  -e PLAYLIST_ID=your_playlist_id \
  -e PLAYERS=Alice,Bob,Carol,Dave \
  -e BASE_URL=https://your-domain.example \
  -e COOKIE_SECRET=$(openssl rand -hex 32) \
  <your-dockerhub-user>/song-randomizer:latest

⁠Environment

VariableRequiredPurpose
SPOTIFY_CLIENT_IDyesSpotify app client id (PKCE, no secret)
PLAYLIST_IDyesSpotify playlist to roulette from
PLAYERSyesComma-separated player names
BASE_URLyesPublic origin, e.g. https://roulette.example.com
PORTnoDefaults to 3000
COOKIE_SECRETyesRandom 32+ char string, signs the PKCE cookie
ADMIN_PASSWORDnoEnables the /admin panel (player management, resets, spin logs). Empty = admin disabled, resets open
APP_PASSWORDnoPassword-protects the wheel itself (30-day session cookie). Empty = open

⁠First run

  1. Register a Spotify app at developer.spotify.com/dashboard⁠. Copy the client id.
  2. Add the redirect URI: ${BASE_URL}/api/auth/callback. In dev mode, allowlist the host account under User Management.
  3. Requested scopes: playlist-read-private, user-read-playback-state, user-modify-playback-state. The host account must be Premium for playback control.
  4. Start the container, visit ${BASE_URL} in a browser, tap Connect Spotify, and complete the OAuth flow once. Tokens land in /data/state.json and refresh automatically.

Full deployment notes (Apache reverse-proxy vhost, HTTPS): see DEPLOY.md⁠.

⁠Tags

  • latest — the newest published tag
  • X.Y.Z — pinned version
  • X.Y — floats within a minor

⁠Data

State lives in an SQLite database at /data/roulette.db inside the container (a legacy state.json from older versions is imported automatically on first boot). Mount a named Docker volume so it survives image upgrades:

-v roulette-state:/data

docker compose down -v will remove that volume, so avoid it unless you want a hard reset.

Tag summary

Content type

Image

Digest

sha256:fb97d5d39…

Size

62.4 MB

Last updated

3 months ago

docker pull gatoserio/song-randomizer