SETUP · 05
How to pull a new version, rebuild only what changed, and what to check when the stream goes quiet. Liquidsoap and the Controller COPY source at build time, so docker compose restart does not pick up code changes. You need up -d --build.
KEEPING IT UP TO DATE
| If this changed | Rebuild |
|---|---|
controller/src/** | controller |
liquidsoap/radio.liq | broadcast |
web/** | web (prod) · hot-reload (dev) |
docker/Caddyfile | just restart caddy (mounted) |
docker-compose*.yml | up -d (compose decides) |
| README / TODO / docs | nothing |
A manual deploy usually looks like this: pull, rebuild what changed (controller and web here), then check the stream is back.
git pull --ff-only
docker compose up -d --build controller web
./scripts/health-check.shIf you installed via curl cli.getsubwave.com | sh, two commands cover the two things you might want to update:
subwave updatesubwave self-updatesubwave update wraps docker pull + up -d and knows which compose file is live. self-update re-runs the installer in place.
If you're pulling prebuilt images from ghcr.io/perminder-klair/subwave-* without the CLI, the rebuild step becomes a pull (pin SUBWAVE_VERSION in .env first):
docker compose pull
docker compose up -dSame flow on docker-compose.byo.yml, just swap the file flag.
The subwave-deploy skill at .claude/skills/subwave-deploy/ does the whole loop for you: pull, work out what changed, rebuild only the affected services, and confirm the stream is healthy. Open a Claude Code session in the repo and say "deploy subwave" or "pull and restart".
WHEN AN UPDATE LANDS BADLY
Two minutes of preparation makes this a command rather than an investigation. Before you update, take a backup from Settings → Backup — it zips your settings, show schedule and the library tag database, which is the expensive thing to rebuild — and write down the version you are on.
grep SUBWAVE_VERSION .env # image installs
git describe --tags # clone installsRolling back is then a version change plus a recreate. On an image install, move the pin backwards; every service reads the same variable, so one line moves the whole stack together:
# .env
SUBWAVE_VERSION=1.4.2docker compose pull
docker compose up -dOn a clone, check out the previous tag instead:
git log --oneline -10
git checkout <previous-tag>
docker compose up -d --buildstate/ does not roll back with the images. Settings a newer version added are dropped on the older version's first save, and the library database migrates forward only. So going back one release is routine; going back several, or across a release whose notes mention a schema change, is the case where you restore that backup.
Admin credentials come from ADMIN_USER and ADMIN_PASS in the root .env, and only from there — nothing an upgrade does to your station data can change them. Compose reads that file when a container is recreated, not restarted, so a stale container is the usual cause:
docker compose exec controller printenv ADMIN_USER
docker compose up -d --force-recreate controllerThe full procedure — every install shape, plus recovery for a silent stream and a restart-looping controller — is in docs/updating.md ↗.
WHEN THINGS GO WRONG
docker compose logs -f controllerdocker compose logs -f broadcastnpm start opens a menu. Its doctor option runs a diagnostic sweep, and logs tails any service without the long compose flags.RUNNING THE STATION
Installation is just the start. Tuning personas, scheduling shows, picking an LLM provider, and managing jingles all happen in the admin console. That's covered in the manual's Admin & Settings page.