Browser-based platform for streaming containerized desktops and applications to end users with enterprise orchestration and data loss prevention.
Table of Contents#
- Overview
- Architecture
- Installation
- SSL Certificate Configuration
- User and Group Management
- Workspace Images
- Network Configuration
- Persistent Profiles and Storage
- Backup and Restore
- API Integration
- Troubleshooting
- See Also
- 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:
| Component | Role | Default Port |
|---|---|---|
| kasm_proxy | Nginx reverse proxy, SSL termination | 443 |
| kasm_api | REST API and web management UI | 8080 |
| kasm_manager | Session orchestration and scheduling | - |
| kasm_agent | Runs on each Docker host, manages containers | 443 |
| kasm_db | PostgreSQL database for state and configuration | 5432 |
| kasm_guac | Apache Guacamole for RDP/SSH connections | - |
| kasm_redis | Redis for session caching | 6379 |
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.shThe installer will:
- Pull all required Docker images
- Generate self-signed SSL certificates
- Create the PostgreSQL database
- Start all services
- 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 managerOn 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 --upgrade4. SSL Certificate Configuration#
4.1 Replace Self-Signed Certificates#
By default, KASM generates self-signed certificates. Replace them with valid certificates:
- Stop KASM services:
sudo /opt/kasm/bin/stop- 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- If using a certificate chain, concatenate intermediate certificates into the
.crtfile:
cat domain.crt intermediate.crt > /opt/kasm/current/certs/kasm_nginx.crt- Start KASM services:
sudo /opt/kasm/bin/start4.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:
- admin@kasm.local - Full administrative access
- user@kasm.local - Standard user access
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 Setting | Purpose |
|---|---|
| Image permissions | Which workspace images the group can launch |
| Session limits | Maximum concurrent sessions per user |
| Keepalive duration | How long idle sessions persist |
| DLP controls | Clipboard, upload/download, printing permissions |
| Audio/video | Microphone 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 1000Build and push:
docker build -t registry.example.com/kasm-custom:1.0 .
docker push registry.example.com/kasm-custom:1.07. Network Configuration#
7.1 Port Requirements#
| Port | Protocol | Purpose |
|---|---|---|
| 443 | TCP | Web UI and workspace streaming |
| 443 | TCP | Agent-to-manager communication |
| 5432 | TCP | Database (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 zonekasm-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 --reload8. 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/start9.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/start9.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 -delete10. 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#
| Method | Endpoint | Purpose |
|---|---|---|
| POST | /api/public/login | Authenticate and get token |
| GET | /api/public/get_users | List all users |
| POST | /api/public/create_user | Create a new user |
| POST | /api/public/request_kasm | Launch a workspace session |
| POST | /api/public/destroy_kasm | Terminate a workspace session |
| GET | /api/public/get_kasms | List active sessions |
| GET | /api/public/get_images | List 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 kasmUseful 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#
| Issue | Cause | Solution |
|---|---|---|
| White screen after login | Browser WebSocket blocked by proxy or firewall | Ensure reverse proxy passes Upgrade and Connection headers |
| Image fails to pull | Missing tag in image name or registry auth failure | Add explicit tag; configure registry credentials in Admin > Registries |
| Session stuck in "starting" | Agent cannot communicate with manager | Verify agent token; check HTTPS connectivity on port 443 between hosts |
| Null user_id in user_groups table | Orphaned group memberships from deleted users | DELETE FROM user_groups WHERE user_id IS NULL; via psql |
| High CPU on agent | Too many concurrent sessions or GPU passthrough misconfigured | Reduce session limits; verify NVIDIA runtime is correctly installed |
| Cannot upload/download files | DLP policy restricting transfers | Check group DLP settings under Admin > Groups |
| Database connection refused | kasm_db container not running | docker start kasm_db; check Docker logs for OOM or disk space issues |
| SSL certificate warnings | Self-signed certificate or expired cert | Replace with valid certificates per Section 4 |
| Audio not working | PulseAudio not configured in image | Use KASM images with audio support; enable audio in group settings |