A Docker sbx mixin kit that solves two problems when running Claude Code in sandboxes:
~/.claude/settings.jsonis overwritten on every sandbox creation (docker/sbx-releases#113)- Audio (notifications, voice mode) doesn't work because sandboxes have no access to host audio devices (docker/sbx-releases#66)
sbx recreates agent config files (~/.claude/) on every sandbox creation, even from templates. This kit works around it by placing an init.sh script in ~/.sbx/ (untouched by sbx) and running it as a startup command — after sbx's own init — to overwrite settings.json with your desired configuration.
Since sbx 30, sandboxes can reach host services through host.docker.internal. The kit uses allowedDomains to permit TCP traffic to PulseAudio on the host, and sets PULSE_SERVER so all audio clients in the sandbox connect transparently.
sandbox (paplay) -> host.docker.internal:4713 -> host PulseAudio/PipeWire
This enables both playback and recording — notifications and voice mode work.
On the host, enable PulseAudio/PipeWire TCP:
pactl load-module module-native-protocol-tcp auth-anonymous=1To make this persistent, add
load-module module-native-protocol-tcp auth-anonymous=1to~/.config/pulse/default.pa(PulseAudio) or configure it via PipeWire.
No sbx policy changes required — the kit's allowedDomains handles network access.
sbx run claude --kit ./path/to/sbx-claude-kit/zip -r sbx-claude-kit.zip spec.yaml files/
sbx run claude --kit sbx-claude-kit.zipsbx kit add <sandbox-name> ./path/to/sbx-claude-kit/sbx-claude-kit/
├── spec.yaml # Kit manifest: network, env vars, install & startup commands
├── notify-server.py # (Optional) HTTP-based notification server for older sbx versions
└── files/
└── home/
└── .sbx/
├── init.sh # Startup script: settings.json injection
└── statusline-command.sh # Claude Code status line script
sox+libsox-fmt-pulse— audio recording/playback with PulseAudio backendpulseaudio-utils—paplay,parecordsound-theme-freedesktop— standard notification sounds
Edit files/home/.sbx/init.sh to change the settings.json content. The current defaults include:
- Bypass permissions mode
- Voice mode enabled
- Auto-compact disabled
- Notification hook (sound on task completion)
- Status line with model name and context window usage
If your sbx version doesn't support host.docker.internal for non-HTTP TCP, notify-server.py provides an HTTP-based alternative for notification sounds only. Run it on the host:
python3 notify-server.pyThen use curl -s http://172.17.0.1:8888/ as the notification hook command.
For older sbx versions, you can also use a socat tunnel through the HTTP CONNECT proxy — see this comment for details.
- docker/sbx-releases#113 —
~/.claudeconfig not persisted - docker/sbx-releases#66 — Voice mode / audio not working in sandboxes
- docker/sbx-releases#147 — Non-HTTP TCP access to host services