KASM Container Build
Packaging Applications for Kasm Workspaces
This guide covers the technical workflow for packaging desktop GUI applications into custom Docker images for Kasm Workspaces, registering them in the database and web interface, configuring advanced features, and understanding display server architecture (X11 vs. Wayland).
1. Selecting a Base Image
Kasm Workspaces runs applications inside containerized desktop environments streamed via KasmVNC. Always extend an official Kasm base image to ensure compatibility with session management, clipboard synchronization, and dynamic resizing:
| Base Image | OS | Desktop Environment | Recommended Use Case |
|---|---|---|---|
kasmweb/terminal:1.19.0-rolling-weekly |
Ubuntu 22.04 | XFCE4 + Terminal | GUI utilities, editors, lightweight tools |
kasmweb/core-ubuntu-jammy:1.16.0 |
Ubuntu 22.04 | Bare XFCE4 | Minimal custom desktop builds |
kasmweb/core-debian-bookworm:1.16.0 |
Debian 12 | Bare XFCE4 | Debian-focused software packaging |
kasmweb/desktop:1.16.0 |
Ubuntu 22.04 | Full XFCE4 + Apps | Full desktop environments |
2. Dockerfile Packaging Workflow
Key Packaging Rules
- User Isolation: Official Kasm base images run under non-root user
1000:1000(kasm-user). Switch toUSER rootfor package installation and explicitly switch back toUSER 1000at the end of the Dockerfile. - Autostart Configuration: To launch an application automatically when the workspace opens, copy an XFCE
.desktopshortcut into/home/kasm-user/.config/autostart/. - Custom Startup Scripts: For applications requiring pre-launch environment variables or wrapper logic, place a script in
/dockerstartup/custom_startup.sh.
Example Dockerfile (kasmweb/moebius:latest)
FROM kasmweb/terminal:1.19.0-rolling-weekly
USER root
# Install required X11, GTK3, and audio runtime dependencies
RUN apt-get update && \
apt-get install -y --no-install-recommends \
wget curl libnotify4 libnss3 libxss1 libxtst6 xdg-utils \
libsecret-1-0 libgbm1 libasound2 && \
wget -q -O /tmp/Moebius.deb https://github.com/blocktronics/moebius/releases/latest/download/Moebius.deb && \
apt-get install -y /tmp/Moebius.deb && \
rm -rf /var/lib/apt/lists/* /tmp/Moebius.deb && \
mkdir -p /home/kasm-user/Desktop /home/kasm-user/.config/autostart && \
cp /usr/share/applications/moebius.desktop /home/kasm-user/Desktop/moebius.desktop && \
cp /usr/share/applications/moebius.desktop /home/kasm-user/.config/autostart/moebius.desktop && \
chmod +x /home/kasm-user/Desktop/moebius.desktop && \
chown -R 1000:1000 /home/kasm-user/Desktop /home/kasm-user/.config
USER 1000
Building inside Standalone Kasm Containers
When running standalone Kasm Workspaces (lscr.io/linuxserver/kasm), Docker images must be built inside the Kasm container engine (kasm):
sudo docker exec -i kasm docker build -t kasmweb/moebius:latest - < Dockerfile
3. Registering the Workspace in the Web Interface
Automated Database Registration (kasm_db)
In standalone Kasm deployments, workspaces can be registered directly in the PostgreSQL database (kasm_db). Each entry in the images table defines the container parameters, and group_images grants access to user groups.
[!IMPORTANT] Unused foreign-key UUID columns (
session_banner_id,server_id,zone_id,filter_policy_id,server_pool_id) must be explicitly set toNULL. Empty strings ('') cause PostgreSQL UUID syntax errors.
-- 1. Insert Workspace definition into images table
INSERT INTO images (
image_id, cores, description, docker_registry, docker_token, docker_user,
image_src, enabled, available, friendly_name, hash, memory_bytes, name,
session_banner_id, session_banner_force_disabled, x_res, y_res, run_config,
volume_mappings, persistent_profile_path, restrict_to_network, restrict_network_names,
allow_network_selection, restrict_to_server, server_id, exec_config,
restrict_to_zone, zone_id, filter_policy_id, filter_policy_force_disabled,
categories, require_gpu, gpu_count, gpu_graphics_acceleration, gpu_video_encoding,
hidden, notes, override_egress_gateways, image_type, server_pool_id, link_url,
cpu_allocation_method, uncompressed_size_bytes, launch_config, rdp_client_type,
is_remote_app, remote_app_icon, remote_app_name, remote_app_program, remote_app_args,
created_at, updated_at, enforce_workspace_persistence
) VALUES (
'a1111111-60eb-4000-a000-0000000060eb', 2,
'Moebius ANSI and ASCII Art Editor full desktop client.',
'https://index.docker.io/v1/', NULL, NULL,
'img/thumbnails/terminal.png', true, true, 'Moebius', NULL, 2902458368,
'kasmweb/moebius:latest', NULL, false, 1280, 720, '{"hostname": "moebius"}',
'{}', '/data/kasm_profiles/{username}/', false, '[]', false, false, NULL, '{}',
false, NULL, NULL, false, '["Design"]', false, 0, '["MESA"]', '["SW"]',
false, NULL, false, 'Container', NULL, NULL, 'Inherit', 1500000000, '{}', NULL,
false, NULL, NULL, NULL, NULL, NOW(), NOW(), true
) ON CONFLICT (image_id) DO NOTHING;
-- 2. Assign image to default All Users group (68d557ac-4cac-42cc-a9f3-1c7c853de0f3)
INSERT INTO group_images (group_image_id, group_id, image_id)
VALUES (
'a2222222-60eb-4000-a000-0000000060eb',
'68d557ac-4cac-42cc-a9f3-1c7c853de0f3',
'a1111111-60eb-4000-a000-0000000060eb'
) ON CONFLICT (group_image_id) DO NOTHING;
Manual UI Registration
4. Advanced Configuration Options
When packaging complex software, evaluate these key operational options:
1. Persistent Profiles (persistent_profile_path)
- Purpose: Retains user files, application settings, and browser profiles across session restarts.
- Configuration: Set
persistent_profile_pathto/data/kasm_profiles/{username}/. - Behavior: When a session launches, Kasm bind-mounts the user's persistent directory to
/home/kasm-user/. Setenforce_workspace_persistence = trueto prevent unmanaged ephemeral sessions.
2. GPU Hardware Acceleration (require_gpu, run_config)
- Purpose: Offloads WebGL, 3D rendering, and video decoding to host GPUs (NVIDIA/AMD/Intel).
- Configuration:
- Set
require_gpu = trueandgpu_count = 1. - For Intel/AMD integrated graphics, pass
/dev/dridevice mappings inrun_config:{"devices": ["/dev/dri:/dev/dri"]} - For NVIDIA GPUs, ensure NVIDIA Container Toolkit is enabled and set
gpu_graphics_acceleration: ["NVIDIA"].
- Set
3. Audio Stream Forwarding
- Purpose: Streams application sound to the web browser.
- Configuration: Kasm base images include ALSA and PulseAudio (
pulseaudio -D) bridged to WebRTC / WebSocket audio codecs. Ensure packages installlibasound2andpulseaudio-utils.
4. Network Isolation & Security (restrict_to_network)
- Purpose: Restricts container egress or connects workspaces to internal backend VLANs/docker networks.
- Configuration: Set
restrict_to_network = trueand specify target Docker network names inrestrict_network_names:["infra_net", "isolated_workspaces"]
5. Display Server Architecture: X11 vs. Wayland
1. Current KasmVNC Standard (X11)
- Architecture: Official Kasm Workspaces desktop containers (
kasmweb/desktop,kasmweb/terminal) operate on the X11 display server protocol usingXvfb/Xorgvirtual framebuffers on display:1. - Why X11 is Default:
- Input Injection: Keyboard and mouse event simulation across web browsers maps reliably to X11 input extensions (
libxtst6). - Dynamic Resolution Resizing: Automatic desktop resizing when browser windows resize relies on
xrandr/ X11 Resize and Rotate extensions. - Clipboard Synchronization: Web-to-desktop clipboard sharing uses standard X11 selection buffers (
PRIMARYandCLIPBOARD).
- Input Injection: Keyboard and mouse event simulation across web browsers maps reliably to X11 input extensions (
2. Wayland & Xwayland Support
- Can Kasm run Wayland?: Yes. Modern KasmVNC releases support Wayland compositors (such as Sway or Weston) via Xwayland and virtual DRM/KMS backend framebuffers.
- Limitations in Wayland Mode:
- Clipboard & Capture: Pure Wayland restricts client-to-client screen capture and clipboard access by design. Applications running natively under Wayland require
xdg-desktop-portal-wlror compositor-specific protocols to share clipboards with KasmVNC. - Application Compatibility: Most packaged Linux GUI applications (Electron, GTK3, Qt5) run under X11 or Xwayland by default. For production packaging in Kasm Workspaces, X11 remains the recommended display server unless testing specialized Wayland-only compositors.
- Clipboard & Capture: Pure Wayland restricts client-to-client screen capture and clipboard access by design. Applications running natively under Wayland require