Note
AI Disclaimer: This application and codebase were created almost entirely by Google Gemini agents.
A sleek, self-hosted web application that acts as a front-end for streamrip, enabling you to easily search, queue, and download high-resolution music albums directly to your server. MusicRequest makes it effortless to build your digital library—while ensuring your audio files are saved securely on your host machine without passing through the browser.
# Build
docker build -t musicrequest .
# Run
docker run -d \
--name musicrequest \
-p 8080:8080 \
-v /path/to/your/music:/music \
-v /path/to/your/config:/config \
-e APP_PASSCODE=your_secure_passcode \
musicrequestThen open http://localhost:8080 and enter the passcode.
Streamrip needs a config.toml with your Qobuz credentials. Create it on your host machine:
The easiest way is to run streamrip once to generate the default config, then edit it:
# Run a temporary container to generate the default config
docker run --rm -v /path/to/your/config:/config musicrequest \
bash -c "rip --config-path /config/config.toml config list"This creates /path/to/your/config/config.toml with all default values.
Because email/password authentication is often unreliable with Qobuz, it is recommended to use authentication tokens extracted directly from your browser.
Edit the config.toml file:
nano /path/to/your/config/config.tomlUpdate the [qobuz] section to enable token authentication:
[qobuz]
quality = 3 # 1: 320kbps MP3, 2: 16/44.1, 3: 24/≤96, 4: 24/≥96
download_booklets = true
use_auth_token = true
email_or_userid = "your_user_id" # Found in Qobuz API requests
password_or_token = "your_x_user_auth_token"
# Leave these empty — streamrip will auto-populate on first use
app_id = ""
secrets = []To extract your authentication token and User ID:
- Log into the Qobuz web player (
play.qobuz.com) in your web browser. - Open your browser's Developer Tools (usually
F12or right-click ->Inspect). - Go to the Network tab and filter by
api.qobuz.com. - Refresh the page or start playing a song.
- Click on one of the API requests in the list (e.g.,
getorgetUser). - In the Request Headers section, find the
x-user-auth-tokenheader and copy its value. Paste this intopassword_or_token. - To find your
user_id, look at the Payload (or Query String Parameters) for that same API request. You will see auser_idparameter. Copy its value and paste it intoemail_or_userid. (Note: Both values can often also be found in the Application / Storage tab under Local Storage forhttps://play.qobuz.com)
In the [downloads] section, set the folder to match the container mount point:
[downloads]
folder = "/music"Run the container interactively to trigger the initial Qobuz login (this populates app_id and secrets):
docker run --rm -it \
-v /path/to/your/config:/config \
musicrequest \
rip --config-path /config/config.toml search qobuz album "test"This will authenticate with Qobuz and save the session tokens back to config.toml.
Create two datasets on your TrueNAS pool:
| Dataset | Purpose | Example Path |
|---|---|---|
| Config | config.toml storage |
/mnt/your_pool/apps/musicrequest/config |
| Music | Downloaded music library | /mnt/your_pool/media/music |
Set permissions to UID/GID 568 (the TrueNAS apps user):
# SSH into TrueNAS
sudo chown -R 568:568 /mnt/your_pool/apps/musicrequest/config
sudo chown -R 568:568 /mnt/your_pool/media/music- In TrueNAS SCALE, go to Apps → Discover → Custom App
- Configure:
| Setting | Value |
|---|---|
| Application Name | musicrequest |
| Image Repository | musicrequest (or your registry path, e.g., ghcr.io/youruser/musicrequest) |
| Image Tag | latest |
- Container Environment Variables:
| Variable | Value |
|---|---|
APP_PASSCODE |
Your chosen passcode |
STREAMRIP_CONFIG_PATH |
/config/config.toml |
MUSIC_DIR |
/music |
SEARCH_LIMIT |
10 |
- Port Forwarding:
| Container Port | Node Port | Protocol |
|---|---|---|
8080 |
8080 (or your preferred port) |
TCP |
- Host Path Volumes:
| Host Path | Mount Path | Description |
|---|---|---|
/mnt/your_pool/apps/musicrequest/config |
/config |
Streamrip configuration |
/mnt/your_pool/media/music |
/music |
Music download destination |
-
Security Context:
- Run as User:
568 - Run as Group:
568
- Run as User:
-
Click Install and wait for the container to start.
Open http://<truenas-ip>:8080 in your browser. You should see the passcode lock screen.
If you're exposing MusicRequest to the internet, use Nginx Proxy Manager for HTTPS and additional access control.
- Open Nginx Proxy Manager (
http://<truenas-ip>:81) - Go to Proxy Hosts → Add Proxy Host
- Configure:
| Setting | Value |
|---|---|
| Domain Names | music.yourdomain.com |
| Scheme | http |
| Forward Hostname / IP | <truenas-ip> |
| Forward Port | 8080 |
| Block Common Exploits | ✅ |
| Websockets Support | ✅ (needed for SSE) |
- SSL Tab:
- Request a new SSL Certificate (Let's Encrypt)
- Force SSL: ✅
- HTTP/2 Support: ✅
For defense-in-depth (HTTP Basic Auth on top of the app's passcode):
- Go to Access Lists → Add Access List
- Name:
MusicRequest Auth - Authorization Tab: Add a username/password
- Access Tab: Satisfy Any, allow
all - Go back to your Proxy Host → edit → set Access List to
MusicRequest Auth
This gives you two layers of protection:
- Nginx Basic Auth — first barrier at the reverse proxy level
- App Passcode — second barrier within the application itself
Add this to the Advanced tab of your Proxy Host to optimize SSE streaming:
proxy_buffering off;
proxy_cache off;
proxy_set_header Connection '';
proxy_http_version 1.1;
chunked_transfer_encoding off;| Variable | Default | Description |
|---|---|---|
APP_PASSCODE |
your_secure_passcode |
Passcode required to access the web UI |
STREAMRIP_CONFIG_PATH |
/config/config.toml |
Path to streamrip configuration file |
MUSIC_DIR |
/music |
Server directory where music is downloaded |
SEARCH_LIMIT |
10 |
Maximum number of search results returned |
Browser (client) MusicRequest (server) Qobuz API
│ │ │
│── GET / ─────────────────▶│ │
│◀── login.html ────────────│ (if not authenticated) │
│── POST /api/auth ────────▶│ verify passcode │
│◀── set session cookie ────│ │
│── GET / ─────────────────▶│ │
│◀── index.html ────────────│ (authenticated) │
│ │ │
│── GET /api/search ───────▶│── album/search ──────────▶│
│◀── JSON results ──────────│◀── JSON ──────────────────│
│ │ │
│── POST /api/download ────▶│ │
│◀── {job_id, queued} ──────│ │
│ │── rip CLI subprocess ────▶│
│ │ (downloads to /music) │
│◀── SSE queue updates ─────│ │
MIT