Skip to content
docker · kasm · workspace · discord · cloakbrowser

Discord + browserworkspace

The production workspace image used by the kasm-vpn Deployment. It extends kasmweb/discord with CloakBrowser so a single KASM session exposes Discord and a browser side-by-side — the browser is the canonical screen-share target streamed through Discord's video feature.

Self-healing desktop

A custom startup script spawns three supervisor loops that poll every 3–5 seconds via pgrep and relaunch CloakBrowser, Discord, or the nav_shim if they exit — no manual session restart.

  • cloak_loop — respawns the bundled Chromium fork.
  • discord_loop — respawns the upstream Discord.
  • nav_shim_loop — respawns the URL launcher shim.
kasm-voidApp
kasmweb/discordBase
CloakBrowserBundles
KBVELicense

What it gives you

Features

Discord + browser bundle

One supervised container exposes Discord and a browser side-by-side for in-session screen-share.

Supervisor auto-respawn

Three background loops relaunch any component that exits, keeping the desktop populated after a crash.

Reproducible browser

A known Chromium build gives consistent stream fonts and codecs across sessions.

Owned resource limits

Bundling lets KBVE own requests/limits against one artifact instead of patching a vendor tag.

Guarded URL launcher

The nav_shim exposes only CDP Page.navigate behind bearer auth, a scheme allowlist, and a Cilium NetworkPolicy.

Supervisors

Crash recovery

/dockerstartup/custom_startup.sh spawns three background supervisors:

LoopProcess matched (pgrep -f)Action
cloak_loopcloakbrowserRelaunches /opt/cloakbrowser/cloakbrowser $CLOAK_APP_ARGS $START_URL
discord_loop`discordelectron`
nav_shim_loopnav_shim.pyRelaunches python3 /dockerstartup/nav_shim.py

Each loop polls every 3–5 seconds. Closing the Discord window or the browser window from the desktop triggers a respawn — no manual KASM session restart needed.

The original kasmweb/discord startup script is preserved as /dockerstartup/discord_startup.sh so its arg-handling, profile setup, and maximize logic continue to work unchanged.

Desktop shortcuts + helper scripts (v0.0.5)

Section titled “Desktop shortcuts + helper scripts (v0.0.5)”

The Desktop ships with launcher icons so the operator does not have to remember paths. Each .desktop entry is built into the image at /home/kasm-user/Desktop/ and the underlying scripts live in /home/kasm-user/scripts/.

IconAction
TerminalOpens xfce4-terminal (the package is now installed)
DiscordDirect launcher for /usr/share/discord/Discord (host-update skipped)
CloakBrowserDirect launcher for the bundled Chromium fork
Open URL in Browserzenity prompt → posts to the local nav_shim (falls back to a fresh cloakbrowser --new-window if the shim is down)
Reload CloakBrowserKills cloakbrowser, clears the Singleton* locks; the supervisor respawns it in ~3s
Reset DiscordStops Discord, clears Cache//Code Cache//GPUCache//Shared Dictionary/, re-seeds SKIP_HOST_UPDATE

scripts/seed-discord-config.sh writes SKIP_HOST_UPDATE: true to ~/.config/discord/settings.json before every Discord launch. The upstream Discord-on-Linux build otherwise attempts a self-update on each boot, which fails inside the gluetun-tunneled namespace and leaves the desktop without a Discord window.

cloak_loop now passes --user-data-dir=/home/kasm-user/.config/cloakbrowser --disable-software-rasterizer and clears stale SingletonLock/SingletonSocket files before each respawn. The loop also tracks an exponential backoff when the binary exits in under 2 seconds and tails the last few lines of /tmp/cloakbrowser.log so the failure is visible from kubectl logs.

Configuration

Runtime env

VariableDefaultNotes
START_URLhttps://kbve.comLaunch URL for the cloakbrowser instance
CLOAK_APP_ARGS(chromium defaults)Override the full cloakbrowser arg list
LAUNCH_DISCORD1Set to 0 to disable the Discord supervisor
LAUNCH_CLOAK1Set to 0 to disable the browser supervisor
LAUNCH_NAV_SHIM1Set to 0 to disable the URL launcher shim
NAV_SHIM_PORT9998Shim listens on this port (0.0.0.0)
CDP_PORT9222Cloakbrowser CDP port (bound to 127.0.0.1)
URL_LAUNCHER_TOKEN(k8s secret)Reuses kasm-vnc-pw value as bearer token
VNC_PW(k8s secret)Provided by the kasm Deployment
APP_ARGS(inherited)Discord-side Electron args, consumed upstream

Ops

Resources & build

The workspace container in apps/kube/kasm/manifest/deployment.yaml is sized for Discord + a browser tab + a screenshare encoder running in parallel:

CPUMemory
requests24Gi
limits48Gi

The Gluetun sidecar keeps its own modest profile (100m/128Mi request, 500m/384Mi limit) — bumping it does not buy noticeable latency since the VPN tunnel is bandwidth-, not CPU-bound.

Terminal window
npx nx run kasm-void:container
npx nx run kasm-void:test

Published tags land at ghcr.io/kbve/kasm-void:<version>; the post-publish chore workflow syncs the Deployment image pin to match version.toml.

Questions

Frequently asked

What is the KASM Void image?

kasm-void is the production workspace image used by the kasm-vpn Deployment. It extends kasmweb/discord with CloakBrowser so the KASM session exposes both Discord and a browser side-by-side, with the browser as the canonical Discord screen-share target.

Why bundle Discord and a browser instead of using the stock image?

The stock kasmweb/discord ships only Discord and leaves an empty desktop when closed. Bundling gives a known reproducible browser binary for consistent stream fonts and codecs and lets KBVE own resource requests and limits against a single artifact.

How does KASM Void keep the desktop populated after a crash?

A custom startup script spawns three supervisor loops (cloak_loop, discord_loop, nav_shim_loop) that poll every 3 to 5 seconds via pgrep and relaunch CloakBrowser, Discord, or the nav_shim if they exit, so no manual KASM session restart is needed.