eXstream is a Xi-based music streaming web app with separate services for ingress, auth, file storage, playlists, and the web player.
api: Traefik ingress and reverse proxy. Protected routes use a ForwardAuth helper that verifies the bearer JWT and forwardsX-UsernameandX-Role.auth: Xi service for registration, login, reset password, token verification, and user profile. Default port:4001.playlist: Xi service for playlist CRUD and music search. Default port:5001.file: Xi file service for create, read, update, delete, and list. Default port:6001.web: React JavaScript music player UI with Tailwind, shadcn-style UI primitives, and Zustand. Default port:7001.
- Auth:
auth/api-spec.yaml - Playlist:
playlist/api-spec.yaml - File:
file/api-spec.yaml
docker compose up --buildThe Xi service images install Xi with Homebrew. If the code-by-sia/x Homebrew tap is private, make sure GitHub SSH auth is available to Docker/Colima before building:
ssh -T git@github.com
docker compose build- Web UI: http://localhost:7001
- API gateway: http://localhost:8080
- Traefik dashboard: http://localhost:8081
- Auth service: http://localhost:4001
- Playlist service: http://localhost:5001
- File service: http://localhost:6001
Set a shared JWT secret when needed:
JWT_SECRET="change-me" docker compose up --buildThe auth service seeds two development users on startup:
| Username | Password | Role | Profile |
|---|---|---|---|
admin |
admin123 |
ADMIN |
Admin |
test |
test123 |
USER |
Test Listener |
The playlist service seeds initial royalty-free generated music for the test user:
| Playlist | Tracks |
|---|---|
| Starter Favorites | Midnight Pulse, Glass Harbor, Solar Steps |
| Ambient Loops | Slow Orbit, Clean Room, Open Sky |
Seeded tracks use compact tone: URLs that the web player turns into generated WAV audio at playback time.
xc auth/auth-service.xi
xc playlist/playlist-service.xi
xc file/file-service.xiRun them directly:
./build/auth-service
./build/playlist-service
./build/file-serviceEach service accepts an optional port argument.
cd web
npm install
npm run devThe Vite dev server runs on http://localhost:7001. When running the web app outside Docker, point the dev proxy at the gateway if needed:
VITE_API_TARGET=http://localhost:8080 npm run devIn Docker Compose, the web service runs the Vite dev server with ./web bind-mounted into the container, so React changes hot reload without rebuilding the image.
Useful web routes:
/login: Login and registration./: Music library home./playlists/:id: Deep link to a playlist./search?q=term: Deep link to music search results./admin/music: Admin-only music management.
The web app supports dark mode, mobile-friendly layouts, and PWA installation via its web manifest and service worker. Admin music management uploads audio through the file service, then stores the uploaded file path on playlist tracks.
Run Xi unit tests:
xi test auth/test/auth_test.xi
xi test playlist/test/playlist_test.xi
xi test file/test/file_test.xiRun JavaScript tests:
node --test api/test/*.test.js
cd web && npm testRun service smoke tests:
./scripts/test-services.shRegister:
curl -X POST http://localhost:8080/auth/register \
-H 'Content-Type: application/json' \
-d '{"username":"sia","password":"secret","profileName":"Sia","email":"sia@example.com","avatar":"🎧"}'Create a playlist through the gateway:
curl -X POST http://localhost:8080/playlists \
-H 'Content-Type: application/json' \
-H "Authorization: Bearer $TOKEN" \
-d '{"name":"Favorites","description":"Daily rotation"}'Direct service calls to protected endpoints must include:
X-Username: sia
X-Role: USER