SETUP · WINDOWS
SUB/WAVE runs on Windows through WSL2 — the containers are Linux containers, and the CLI is a Linux binary. There's no subwave.exe and there doesn't need to be: a WSL2 shell gives you the same one-line install everyone else gets. If you'd rather not touch WSL at all, the second path down this page is plain docker compose from PowerShell.
Path A (WSL2) is the recommended one: you get subwave setup, doctor, update and the rest, identical to a Linux host. Path B (PowerShell) skips WSL and drives Docker Desktop with two files and docker compose — fewer moving parts, but you manage the stack by hand.
PATH A · WSL2 + DOCKER DESKTOP
From an Administrator PowerShell. This installs WSL2 and Ubuntu in one go, then wants a reboot:
wsl --installAlready have WSL? Make sure the distro is on version 2 — wsl -l -v should print 2 in the VERSION column. Docker Desktop's integration doesn't work with WSL1.
Install Docker Desktop ↗ with the WSL2 backend, then turn on integration for your distro, which is the step most people miss: Settings → Resources → WSL integration, toggle Ubuntu, apply and restart. Without it, docker simply isn't on PATH inside the shell you're about to use.
Open a WSL shell and check:
docker compose versionFrom the WSL shell (not PowerShell). The installer sees linux-x64 and installs the same binary a Linux server gets:
curl -fsSL https://cli.getsubwave.com | shsubwave setupAccept the default install location — ~/subwave inside WSL. See the callout below on why that matters.
WSL2 forwards localhost, so the station is reachable from your normal Windows browser with no extra plumbing:
http://localhost:7700Other devices on the network need the host's LAN address plus a firewall rule for TCP 7700 (Windows Defender Firewall → Inbound Rules). Check the stack any time with:
subwave doctorInstall into the WSL filesystem (~/subwave), never /mnt/c/.... Windows drives are mounted over a translation layer, and state/library.dbis SQLite in WAL mode: file locking across that boundary is both slow and unreliable, which shows up as random “database is locked” errors during an analysis pass rather than as a clean failure.
Only relevant if you're building from source. Git on Windows converts line endings to CRLF by default, which breaks the shell scripts and container entrypoints the images run — exec format error, or an entrypoint that exits instantly. Run git clone from the WSL shell so the checkout stays LF.
WSL2 takes a share of system RAM that is generous but capped, and the optional heavy sidecars want a lot of it (the analyzer's ceiling is 6g, tts-heavy's is 10g). Create or edit %UserProfile%\.wslconfig, then wsl --shutdown to apply:
[wsl2]
memory=8GB
processors=4The base station is happy in 4 GB. Only raise this if you're enabling heavy analysis or the voice-cloning sidecar.
PATH B · POWERSHELL, NO WSL SHELL
Docker Desktop still uses WSL2 underneath, but you never open a Linux shell. This is the Manual Install path with Windows spellings.
mkdir subwave; cd subwave
curl.exe -O https://raw.githubusercontent.com/perminder-klair/subwave/main/docker-compose.yml
curl.exe -O https://raw.githubusercontent.com/perminder-klair/subwave/main/.env.example
Rename-Item .env.example .env
notepad .envIn PowerShell, curl is an alias for Invoke-WebRequest, which doesn't understand -O and will fail with a parameter error. The .exe suffix calls the real curl that ships with Windows.
Fill in the three required keys — ADMIN_USER, ADMIN_PASS, SITE_URL — save, then:
docker compose up -d
start http://localhost:7700/onboardingThe browser wizard collects Navidrome, the LLM, TTS and the DJ persona, exactly as subwave setup would. From then on the stack is docker compose ps, logs -f, and up -d --pull always to update.
WINDOWS-SPECIFIC NOTES
From inside a container, localhost is the container. Point the wizard at http://host.docker.internal:4533 — the compose files already map that name to the host gateway. Same for Ollama on http://host.docker.internal:11434.
On an x64 PC, analyzer-heavy (CLAP + Demucs) and tts-heavy are amd64 images on an amd64 host — no emulation penalty, unlike Apple Silicon. An NVIDIA card can go further still: Docker Desktop exposes CUDA through WSL2, so the GPU analyzer overlay works. Running native is not the same as running, though: tts-heavy is profile-gated, so it only starts under docker compose --profile tts-heavy up -d (or with COMPOSE_PROFILES=tts-heavy in .env).
Every service is restart: unless-stopped, so tick Start Docker Desktop when you log in and the station returns after a reboot. Note it starts at login, not boot — a headless station box needs autologin, or move it to a Linux host.
A PC that sleeps takes the station off air and drops every listener. If this box is the station, set the power plan to never sleep.
WHAT'S NEXT
Everything past install is platform-neutral: the admin console at /admin runs the station, and Updates & Help covers upgrades and troubleshooting. If you'd rather run this on a machine that never sleeps, Linux and Unraid are the set-and-forget hosts.