Field report: the radio died and kept restarting. The log chain is
unambiguous - "Daemon startup failed" (pulse), then Connection refused on
input.pulseaudio_0 / buffer.consumer_0 / pulse_out, then "Shutdown
started!", then round again.
Three fixes:
* Clear stale pulse runtime state before starting the daemon. /run is part
of the container's writable layer, so "docker restart" - and the loop that
restart:unless-stopped produces - preserves /run/pulse/pid from the killed
daemon; the next start then refuses with "Daemon startup failed", which is
what makes the loop self-sustaining. We only remove it when no pulseaudio
process is actually alive.
* When pulse still won't start, say so loudly and explain the consequence
and the way out (Icecast needs no sound device; comment the pulse tor out),
instead of a one-line WARNING that gets lost above the traceback.
* output.pulseaudio(fallible=true): the local monitor output can now fail
without failing its clock and tearing down the radio. The mic input stays
a hard dependency - documented inline, since removing it changes audio
behaviour and cannot be verified without a liquidsoap runtime.
Also: RADIO_FORCE_SCRIPT=1 re-seeds radio_conjurer.liq from the image
(keeping a .bak). The live script is deliberately never overwritten so hand
edits win - but that also means image fixes never reached volumes seeded
long ago, which is why a running radio can still hold a stale script.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>