Browser-based platform for streaming containerized desktops and applications to end users with enterprise orchestration and data loss prevention.

Table of Contents#

  1. Overview
  2. Architecture
  3. Installation
  4. SSL Certificate Configuration
  5. User and Group Management
  6. Workspace Images
  7. Network Configuration
  8. Persistent Profiles and Storage
  9. Backup and Restore
  10. API Integration
  11. Troubleshooting
  12. See Also
  13. Sources

1. Overview#

KASM Workspaces is a container streaming platform that delivers Linux desktops, browsers, and applications directly to a user's web browser. It uses Docker containers as isolated workspaces, streamed via KasmVNC (a high-performance VNC implementation optimized for web delivery). The platform provides session management, access controls, DLP (Data Loss Prevention) policies, and multi-zone deployment capabilities.

Key features:

  • Browser-based access with no client software required
  • Isolated Docker containers per session
  • Built-in DLP controls (clipboard, upload/download, printing restrictions)
  • LDAP, SAML, and OIDC authentication support
  • Multi-server deployment with agent-based scaling
  • GPU passthrough for graphics-intensive workloads
  • Persistent user profiles across sessions

2. Architecture#

KASM uses a multi-component architecture:

ComponentRoleDefault Port
kasm_proxyNginx reverse proxy, SSL termination443
kasm_apiREST API and web management UI8080
kasm_managerSession orchestration and scheduling-
kasm_agentRuns on each Docker host, manages containers443
kasm_dbPostgreSQL database for state and configuration5432
kasm_guacApache Guacamole for RDP/SSH connections-
kasm_redisRedis for session caching6379

All components run as Docker containers orchestrated by docker-compose. In a multi-server deployment, agents run on separate Docker hosts and communicate with the manager over HTTPS.

3. Installation#

3.1 Prerequisites#

  • Docker and Docker Compose installed
  • Minimum 2 CPU cores, 4 GB RAM (single server)
  • Ports 443 (HTTPS) open
  • Supported OS: Ubuntu 20.04/22.04, Debian 11/12, CentOS 7/8/9, Oracle Linux, RHEL

3.2 Single-Server Installation#

cd /tmp
curl -O https://kasm-static-content.s3.amazonaws.com/kasm_release_<version>.tar.gz
tar -xf kasm_release_<version>.tar.gz
sudo bash kasm_release/install.sh

The installer will:

  1. Pull all required Docker images
  2. Generate self-signed SSL certificates
  3. Create the PostgreSQL database
  4. Start all services
  5. Display the admin credentials and web UI URL

3.3 Multi-Server Installation#

On the database/manager server:

sudo bash kasm_release/install.sh --role db
sudo bash kasm_release/install.sh --role manager

On each agent server:

sudo bash kasm_release/install.sh --role agent --manager-hostname <manager-ip> --manager-token <token>

3.4 Upgrade#

sudo /opt/kasm/bin/stop
cd /tmp
curl -O https://kasm-static-content.s3.amazonaws.com/kasm_release_<new_version>.tar.gz
tar -xf kasm_release_<new_version>.tar.gz
sudo bash kasm_release/install.sh --upgrade

4. SSL Certificate Configuration#

4.1 Replace Self-Signed Certificates#

By default, KASM generates self-signed certificates. Replace them with valid certificates:

  1. Stop KASM services:
sudo /opt/kasm/bin/stop
  1. Replace the certificate and key files:
sudo cp <your_cert> /opt/kasm/current/certs/kasm_nginx.crt
sudo cp <your_key> /opt/kasm/current/certs/kasm_nginx.key
  1. If using a certificate chain, concatenate intermediate certificates into the .crt file:
cat domain.crt intermediate.crt > /opt/kasm/current/certs/kasm_nginx.crt
  1. Start KASM services:
sudo /opt/kasm/bin/start

4.2 Let's Encrypt with Reverse Proxy#

When KASM sits behind a reverse proxy (Nginx, HAProxy), terminate TLS at the proxy and configure KASM to accept HTTP internally. Set the proxy to forward X-Forwarded-Proto: https and configure the KASM zone to use the proxy's address.

5. User and Group Management#

5.1 Default Accounts#

After installation, two accounts are created:

Change both passwords immediately after installation.

5.2 Local User Management#

Manage users through the web UI under Admin > Users:

  • Create, edit, disable, and delete user accounts
  • Assign users to groups
  • Set per-user session limits and DLP policies

5.3 Groups and Permissions#

Groups control access to workspace images and settings:

Group SettingPurpose
Image permissionsWhich workspace images the group can launch
Session limitsMaximum concurrent sessions per user
Keepalive durationHow long idle sessions persist
DLP controlsClipboard, upload/download, printing permissions
Audio/videoMicrophone and webcam passthrough

5.4 LDAP/AD Integration#

Configure under Admin > Authentication > LDAP:

  • LDAP URL: ldaps://<dc-hostname>:636
  • Bind DN: CN=kasm-bind,OU=Service Accounts,DC=example,DC=com
  • Search base: OU=Users,DC=example,DC=com
  • User filter: (sAMAccountName={0})
  • Group filter: (member={0})
  • Enable auto-provisioning to create KASM users on first LDAP login

5.5 SAML/OIDC Integration#

Configure under Admin > Authentication > SAML or OIDC:

  • Provide the IdP metadata URL or upload metadata XML
  • Map IdP attributes to KASM user fields
  • Configure group mapping for automatic role assignment

6. Workspace Images#

6.1 Default Registry#

KASM provides pre-built images from the official registry. Add the registry under Admin > Images > Add Image:

https://index.docker.io/v1/

6.2 Adding Images#

Important: Always include a tag in the Docker image name (e.g., kasmweb/ubuntu-jammy-desktop:1.14.0). Without a tag, KASM may fail to pull and start the image.

Configure images under Admin > Images:

  • Docker Image: Full image reference including tag
  • Friendly Name: Display name in the user workspace launcher
  • Cores/Memory: Resource limits for the container
  • Docker Run Config: JSON object for advanced container options

6.3 Docker Run Config Examples#

Enable TUN device and IPv6 (for VPN containers):

{
  "cap_add": ["NET_ADMIN"],
  "devices": ["/dev/net/tun:/dev/net/tun"],
  "sysctls": {
    "net.ipv6.conf.all.disable_ipv6": "0"
  }
}

Mount a host directory:

{
  "volumes": {
    "/host/shared": {
      "bind": "/home/kasm-user/shared",
      "mode": "rw"
    }
  }
}

GPU passthrough:

{
  "environment": {
    "NVIDIA_VISIBLE_DEVICES": "all",
    "NVIDIA_DRIVER_CAPABILITIES": "all"
  },
  "runtime": "nvidia"
}

6.4 Custom Images#

Build custom images based on KASM base images:

FROM kasmweb/core-ubuntu-jammy:1.14.0
USER root

RUN apt-get update && apt-get install -y \
    firefox \
    libreoffice \
    && rm -rf /var/lib/apt/lists/*

USER 1000

Build and push:

docker build -t registry.example.com/kasm-custom:1.0 .
docker push registry.example.com/kasm-custom:1.0

7. Network Configuration#

7.1 Port Requirements#

PortProtocolPurpose
443TCPWeb UI and workspace streaming
443TCPAgent-to-manager communication
5432TCPDatabase (internal, not exposed by default)

7.2 DNS Configuration#

Each KASM zone requires a DNS entry. For multi-zone deployments:

  • kasm.example.com - Primary management zone
  • kasm-zone2.example.com - Secondary agent zone

7.3 Reverse Proxy Configuration#

Place KASM behind Nginx for additional SSL control and routing:

server {
    listen 443 ssl;
    server_name kasm.example.com;

    ssl_certificate /etc/letsencrypt/live/kasm.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/kasm.example.com/privkey.pem;

    location / {
        proxy_pass https://127.0.0.1:8443;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        # WebSocket support (required for streaming)
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";

        proxy_read_timeout 1800s;
        proxy_send_timeout 1800s;
    }
}

7.4 Firewall Rules#

# Allow HTTPS access
firewall-cmd --permanent --add-service=https
firewall-cmd --reload

8. Persistent Profiles and Storage#

8.1 Persistent Profiles#

Enable persistent home directories so user data survives container restarts. Configure under Admin > Images > Edit Image > Persistent Profile Path:

  • Path: /mnt/kasm_profiles/{username}
  • The directory is mounted into each session container at /home/kasm-user

8.2 Shared Storage#

Mount shared directories into workspace containers via the Docker Run Config:

{
  "volumes": {
    "/srv/shared-data": {
      "bind": "/home/kasm-user/shared",
      "mode": "ro"
    }
  }
}

9. Backup and Restore#

9.1 Backup#

Back up the database and configuration:

# Stop services
sudo /opt/kasm/bin/stop

# Backup database
sudo docker run --rm -v kasm_db_data:/data -v /backup:/backup \
    alpine tar czf /backup/kasm_db_$(date +%Y%m%d).tar.gz -C /data .

# Backup configuration
sudo tar czf /backup/kasm_config_$(date +%Y%m%d).tar.gz /opt/kasm/current/conf/

# Start services
sudo /opt/kasm/bin/start

9.2 Restore#

sudo /opt/kasm/bin/stop

# Restore database
sudo docker run --rm -v kasm_db_data:/data -v /backup:/backup \
    alpine sh -c "rm -rf /data/* && tar xzf /backup/kasm_db_<date>.tar.gz -C /data"

# Restore configuration
sudo tar xzf /backup/kasm_config_<date>.tar.gz -C /

sudo /opt/kasm/bin/start

9.3 Automated Backups#

Create a cron job or systemd timer:

# /etc/cron.daily/kasm-backup
#!/bin/bash
BACKUP_DIR=/backup/kasm
mkdir -p "$BACKUP_DIR"
docker exec kasm_db pg_dumpall -U kasmapp > "$BACKUP_DIR/kasm_db_$(date +%Y%m%d).sql"
find "$BACKUP_DIR" -name "*.sql" -mtime +30 -delete

10. API Integration#

10.1 Authentication#

All API requests require an API key or admin credentials:

curl -k -X POST https://kasm.example.com/api/public/login \
  -H "Content-Type: application/json" \
  -d '{
    "username": "admin@kasm.local",
    "password": "<admin_password>"
  }'

10.2 Common API Endpoints#

MethodEndpointPurpose
POST/api/public/loginAuthenticate and get token
GET/api/public/get_usersList all users
POST/api/public/create_userCreate a new user
POST/api/public/request_kasmLaunch a workspace session
POST/api/public/destroy_kasmTerminate a workspace session
GET/api/public/get_kasmsList active sessions
GET/api/public/get_imagesList available workspace images

10.3 Launch a Workspace via API#

curl -k -X POST https://kasm.example.com/api/public/request_kasm \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <token>" \
  -d '{
    "image_id": "<image-uuid>",
    "enable_sharing": false
  }'

10.4 Database Direct Access#

For advanced troubleshooting, connect to the PostgreSQL database:

sudo docker exec -it kasm_db psql -U kasmapp -d kasm

Useful queries:

-- List all users
SELECT user_id, username, locked FROM users;

-- List active sessions
SELECT * FROM kasms WHERE state = 'running';

-- Check user group membership
SELECT u.username, g.name
FROM user_groups ug
JOIN users u ON ug.user_id = u.user_id
JOIN groups g ON ug.group_id = g.group_id;

Troubleshooting#

IssueCauseSolution
White screen after loginBrowser WebSocket blocked by proxy or firewallEnsure reverse proxy passes Upgrade and Connection headers
Image fails to pullMissing tag in image name or registry auth failureAdd explicit tag; configure registry credentials in Admin > Registries
Session stuck in "starting"Agent cannot communicate with managerVerify agent token; check HTTPS connectivity on port 443 between hosts
Null user_id in user_groups tableOrphaned group memberships from deleted usersDELETE FROM user_groups WHERE user_id IS NULL; via psql
High CPU on agentToo many concurrent sessions or GPU passthrough misconfiguredReduce session limits; verify NVIDIA runtime is correctly installed
Cannot upload/download filesDLP policy restricting transfersCheck group DLP settings under Admin > Groups
Database connection refusedkasm_db container not runningdocker start kasm_db; check Docker logs for OOM or disk space issues
SSL certificate warningsSelf-signed certificate or expired certReplace with valid certificates per Section 4
Audio not workingPulseAudio not configured in imageUse KASM images with audio support; enable audio in group settings

See Also#

Sources#