How to install Spotycast on Debian and Docker
Restore Spotify-controlled playback on legacy Linux streamers without rebuilding your audio system. Deploy Spotycast on a separate Debian/Linux host, select the receiving protocol your player supports, then verify the correct audio path: Icecast HTTP radio for Classic, or a dedicated renderer backend for Premium.
Before you start: three decisions
1. Choose a host
The reference installation uses an AMD64/x86-64 Debian or compatible Linux host/VM with Docker and Compose. Keep the Spotycast bridge separate from your legacy audio appliance.
2. Check your LAN
Spotify discovery and renderer discovery may need local-network visibility. Start on a simple trusted LAN; troubleshoot VLAN, multicast and firewall restrictions only if necessary.
3. Choose an output
Use Classic when your player accepts an HTTP radio URL. Use Premium for a supported Squeezelite/LMS, MPD, Roon or OpenHome renderer backend.
Classic / Free or Premium 3.x?
Use a stable Icecast radio URL
Spotycast Classic uses spotifyd → Liquidsoap → Icecast and publishes an HTTP stream that compatible players can open as radio.
- No Spotycast Premium installation key
- Compressed Spotify source, up to approximately 320 kbps
- Roon Live Radio, LMS and compatible HTTP receivers
- Validate by playing the Icecast mountpoint
Use a direct renderer backend
Premium uses Soloist → PipeWire → dedicated renderer backend, not the Classic Icecast radio output as its primary playback route.
- Spotycast Premium installation key required
- Separate Soloist API key required
- Squeezelite/LMS, MPD, Roon and OpenHome backends
- Validate in Manager and on the receiving renderer
Step 1 — Deploy the Spotycast Docker container
Both installation paths start in the same reference container. You may deploy it with Docker Compose on the Debian host or as a Portainer Stack. The sample below uses the project’s existing reference image and host networking.
Docker Compose — host-network reference
services:
spotycast:
image: chourmovs/debian13-vnc-novnc-ssh:latest
container_name: spotycast
restart: unless-stopped
network_mode: host
privileged: true
shm_size: "1gb"
environment:
USERNAME: "radio"
USER_UID: "1000"
USER_GID: "1000"
SSH_PASSWORD: "${SPOTYCAST_SSH_PASSWORD}"
VNC_PASSWORD: "${SPOTYCAST_VNC_PASSWORD}"
ROOT_PASSWORD: "${SPOTYCAST_ROOT_PASSWORD}"
ALLOW_ROOT_SSH: "no"
VNC_GEOMETRY: "1600x900"
VNC_DEPTH: "24"
ICECAST_PORT: "28000"
volumes:
- /etc/localtime:/etc/localtime:ro
- ./spotycast-data:/data
With network_mode: host, the container uses host ports directly. A ports: mapping is intentionally omitted: it is not used with host networking. Before deployment, set the three password variables through a protected environment file or Portainer environment settings; do not publish actual credentials in a shared YAML file.
Prepare the environment variables
On the Docker host, create the spotycast directory and an environment file with restrictive permissions. Generate distinct values for SSH, VNC and root. Do not copy passwords from a tutorial.
mkdir -p spotycast && cd spotycast
umask 077
printf 'SPOTYCAST_SSH_PASSWORD=%s\n' "$(openssl rand -hex 24)" > .env
printf 'SPOTYCAST_VNC_PASSWORD=%s\n' "$(openssl rand -hex 24)" >> .env
printf 'SPOTYCAST_ROOT_PASSWORD=%s\n' "$(openssl rand -hex 24)" >> .env
chmod 600 .env
nano compose.yml
docker compose config --quiet
docker compose up -d
docker compose ps
compose.yml before running docker compose config. Keep .env private and backed up securely. If your image’s entrypoint has additional password requirements, follow its documentation.Portainer alternative
- Open Stacks → Add stackName the stack
spotycastand paste the same Compose definition. - Set strong environment valuesDefine
SPOTYCAST_SSH_PASSWORD,SPOTYCAST_VNC_PASSWORDandSPOTYCAST_ROOT_PASSWORDas protected stack variables, not tutorial passwords. - Deploy on the trusted LANStart the container, verify its status, then access noVNC only from an authorized machine.
http://<SPOTYCAST-HOST>:6080/vnc.html
The URL is a local network example, not a public web endpoint. Launch LXTerminal in the container desktop to run the installer for your selected edition.
Step 2A — Install Spotycast Classic / Free
Choose this branch if your existing player can open a conventional HTTP radio stream. The reference image includes the Classic installer under /root/binaries.
cd /root/binaries
./spotifyd-free
Let the installer finish and follow its prompts. The Classic playback path is spotifyd → local audio → Liquidsoap → Icecast → HTTP-compatible player.
Step 3 — Verify the output you installed
Check the Icecast HTTP stream
- Start playback to the Spotycast/spotifyd endpoint from Spotify.
- Open the Icecast status page at the configured host and port.
- Confirm a mountpoint is available.
- Open that mountpoint in VLC, ffplay or your target HTTP radio player.
http://<SPOTYCAST-HOST>:28000
vlc http://<SPOTYCAST-HOST>:28000/spotify.aac
ffplay http://<SPOTYCAST-HOST>:28000/spotify.aac
These are reference URLs for port 28000 and an AAC mountpoint. Confirm the real port, mountpoint and codec generated by your installed Classic configuration.
Check the direct renderer path
- Open the Manager and confirm that the selected backend is enabled.
- Check Status and, when needed, Renderer logs.
- Verify that the target renderer is reachable on the LAN.
- Select the Premium Connect endpoint in Spotify and start playback.
- Confirm audible playback on the intended renderer.
Troubleshooting installation problems
Check the component that actually failed; avoid changing networking, credentials and renderer settings simultaneously.
Spotify Connect device missing
Check client/service status, multicast discovery, firewall, Docker networking and LAN visibility. Discovery guide →
Classic stream has no audio
Check the Spotify playback session, Liquidsoap, Icecast status/mountpoint, codec compatibility and radio player output. No audio guide →
Premium backend silent
Confirm both keys, inspect Manager Status and Renderer logs, then check reachability of the specific renderer backend.
Dropouts or buffering
Separate Spotify upstream instability from HTTP buffering, network congestion and receiving backend problems. Dropouts guide →
Useful local checks
supervisorctl status
curl --max-time 5 http://127.0.0.1:28000/status-json.xsl
ss -ltnp | grep 28000
The Icecast checks above apply to Classic and assume its reference port. For Premium, use Manager’s backend-specific Status and Renderer logs first. A failed Classic-only check is not evidence of a Premium failure.