Server Setup
This guide covers installing and configuring the server-side components with Docker. The sweisgerber/snapcast image bundles Snapserver, librespot, and shairport-sync into one container.
For alternative installation methods, see the Snapcast documentation and librespot documentation.
Prerequisites
- A Linux machine such as a Raspberry Pi, old laptop, NAS, or VM.
- Docker and Docker Compose installed.
- Network connectivity to the Wi-Fi HaLow AP, usually wired or bridged.
- A Spotify Premium account if you want Spotify Connect support.
Create Directories
sudo mkdir -p /opt/services/config/snapcast/{config,data}
sudo mkdir -p /opt/services/config/librespot
sudo chown -R 1000:1000 /opt/services/config/snapcast /opt/services/config/librespot
Create docker-compose.yml
Create a compose file at your preferred location, for example /opt/services/docker-compose.yml.
services:
snapcast:
image: docker.io/sweisgerber/snapcast:latest
hostname: snapcast
network_mode: host
environment:
- PUID=1000
- PGID=1000
- START_SNAPCLIENT=true
- START_AIRPLAY=true
- DOCKER_MODS=linuxserver/mods:universal-package-install
- INSTALL_PACKAGES=sox
restart: "unless-stopped"
volumes:
- /etc/localtime:/etc/localtime:ro
- /opt/services/config/snapcast/config:/config/
- /opt/services/config/snapcast/data:/data/
- /opt/services/config/librespot:/var/cache/librespot
Host networking is recommended so mDNS and Spotify Connect discovery work correctly. If you do not use network_mode: host, map Snapcast audio, control, web, and Spotify discovery ports explicitly.
Configure mDNS
Configure Avahi on the Docker host to advertise Snapcast services on the local network. This is not strictly required, but it simplifies endpoint configuration.
sudo apt install avahi-daemon
sudo systemctl enable --now avahi-daemon
Create /etc/avahi/services/snapcast.service:
<?xml version="1.0" standalone='no'?>
<!DOCTYPE service-group SYSTEM "avahi-service.tld">
<service-group>
<name>Snapcast</name>
<service>
<type>_snapcast._tcp</type>
<port>1704</port>
</service>
<service>
<type>_snapcast-ctrl._tcp</type>
<port>1705</port>
</service>
<service>
<type>_snapcast-http._tcp</type>
<port>1780</port>
</service>
</service-group>
sudo systemctl restart avahi-daemon
Start the Container
cd /opt/services
docker compose up -d
docker compose logs -f snapcast
You should see Snapserver, librespot, and shairport-sync starting up.
Snapserver Config
The container reads /config/snapserver.conf, mapped to /opt/services/config/snapcast/config/snapserver.conf on the host. Start from the upstream default config and adjust the values below.
librespot-48k.sh
The ESP32-S3 cannot properley generate the I2S master clock for 44.1 kHz audio, so librespot's output must be resampled to 48 kHz before Snapserver distributes it. librespot-48k.sh runs librespot and pipes its raw PCM output through sox to perform the resampling. The DOCKER_MODS and INSTALL_PACKAGES env vars added above install sox into the container at startup.
Place the script in your config directory and make it executable:
curl -o /opt/services/config/snapcast/config/librespot-48k.sh \
https://abaumann9.github.io/longwave-audio/librespot-48k.sh
chmod +x /opt/services/config/snapcast/config/librespot-48k.sh
Stream Config
Configure Snapserver to launch librespot via the wrapper script at 48 kHz. Add the following to snapserver.conf:
[stream]
sampleformat = 48000:16:2
codec = flac
chunk_ms = 26
buffer = 1000
source = process:///config/librespot-48k.sh?name=LibreSpot&sampleformat=48000:16:2&dryout_ms=2000&wd_timeout=7800&log_stderr=true
| Parameter | Value | Purpose |
|---|---|---|
sampleformat | 48000:16:2 | 48 kHz, 16-bit, stereo — required for ESP32-S3 I2S clock. |
codec | flac | Lossless compression, about 600–900 kbps. |
chunk_ms | 26 | Audio chunk size sent to clients. |
buffer | 1000 | Playback buffer in ms. Increase to 1500–2000 if audio stutters. |
dryout_ms | 2000 | ms of silence before stream is considered idle. |
wd_timeout | 7800 | Watchdog timeout in ms; restarts the process if it hangs. |
log_stderr | true | Forward librespot output to container logs. |
The --zeroconf-port 22382 in librespot-48k.sh must match the exposed Docker port when not using host networking, otherwise Spotify apps may not discover the device.
Restart Snapcast after config changes:
docker compose restart snapcast
Spotify OAuth
librespot requires a one-time OAuth login to link your Spotify account. The server can be headless; complete the browser step from any phone or laptop.
- Watch the container logs with
docker compose logs -f snapcast. - Open the Spotify authorization URL shown in the logs.
- Log in with your Spotify Premium account and approve access.
- If the redirect page does not load, copy the full redirect URL, including the
?code=parameter, and paste it back into the librespot prompt. - Credentials are cached in
/var/cache/librespot, mapped to/opt/services/config/librespot.
Verify Everything
- Open SnapWeb at
http://<server-ip>:1780. - Open Spotify and select the LongWave or Snapcast device.
- Play a track and confirm the stream appears in SnapWeb.
- Flash and provision an endpoint, then confirm it connects to the Snapserver on port
1704.
Troubleshooting
- No OAuth URL: credentials may already be cached. Check whether the device appears in Spotify.
- Expired token: clear
/opt/services/config/librespot/*, restart the container, and repeat OAuth. - No Spotify discovery: verify mDNS, host networking, and the librespot zeroconf port.
- Endpoint cannot connect: verify Snapserver is listening on
1704and the HaLow bridge can reach the server LAN.