Main features:
- Automatic music library scanning from a mounted host folder
- Browse and filter tracks, albums, and artists
- Playlist management (create, update, and organize tracks)
- JWT-based authentication with cookie support
- HTTP audio streaming endpoints
- Realtime scanner updates over WebSocket
- Persistent SQLite database storage via Docker volume
- One-command deployment with Docker Compose
This project runs as one application container:
datastream(NestJS API + scanner + WebSocket + built Vite frontend)
Create root .env:
JWT_SECRET=SUPER_SECRET_KEY
CLIENT_PORT=8080
MUSIC_HOST_PATH=./apps/server/temp-music-dir
COOKIE_SECURE=falseUse this docker-compose.yml:
services:
datastream:
image: sneakyselderey/datastream:latest
environment:
JWT_SECRET: ${JWT_SECRET:-SUPER_SECRET_KEY}
COOKIE_SECURE: ${COOKIE_SECURE:-false}
ports:
- "${CLIENT_PORT:-8080}:3000"
volumes:
- datastream_db:/data
- ${MUSIC_HOST_PATH:-./apps/server/temp-music-dir}:/music:ro
restart: unless-stopped
volumes:
datastream_db:docker compose up -dOpen:
http://localhost:8080
- Browser calls
datastreamon port8080. - NestJS handles API, media streaming, Swagger, WebSocket, and frontend file serving in the same container.
/api/*routes are handled by backend controllers./stream/*routes are handled by backend streaming endpoints./docsserves Swagger/OpenAPI documentation./socket.iois used by scanner progress WebSocket updates.- Other browser page paths are served as SPA routes by the built frontend.
WebSocket path used by frontend:
/socket.io
- SQLite DB is persisted in the named volume
datastream_db. - Music library host path is configurable via
MUSIC_HOST_PATHand is always mounted to fixed container path/music. - Cover cache path is configurable via
COVERS_CACHE_PATH(default:/data/covers). - If you need HTTPS/HTTP/3, place an external reverse proxy in front later (Nginx/Caddy/Traefik/CDN).
apps/server/.envis for non-Docker local backend runs only (npm run start:devinapps/server).

