JustToThePoint English Website Version
JustToThePoint en español
Colaborate with us

Kasm Workspaces

Do, or do not. There is no try, Yoda.

“Home Server

Kasm Workspaces allows users to access their customized desktop environments and applications through a web browser from any location on any device. It uses container technology to create isolated environments, meaning that each workspace is independent, providing a secure and consistent experience.

Using Kasm is like throwing your laptop away after each use and using a different internet connection each time, KASM WORKSPACES.

Installation

The default Kasm Workspaces are configured to require 4GB of memory, 2 cores, and 50 GB (SSD). Kasm Workspaces can be installed on a Virtual Machine or directly on bare metal.In my particular case, I install it in a VM in my Proxmox running Ubuntu Server 22.04 with 4 processors and 16 GB Memory.

The Kasm Workspaces community edition container streaming platform allows users to self-host Kasm on their own servers or computers for free. Notice that there is a five concurrent session limit in the community edition compared to the professional and enterprise plan.

Log into the Web Application running on port 443 at https:// + WEBAPP_SERVER. On the dashboard control panel you will be able to see useful statistics like max active users, successful/fails logins, current sessions, etc.

cd /tmp
curl -O https://kasm-static-content.s3.amazonaws.com/kasm_release_LATEST_RELEASE.tar.gz
# Download the latest version of Kasm Workspaces to /tmp
# kasmweb.com, Documentation, Installation process.

tar -xf kasm_release_LATEST_RELEASE.tar.gz
# Extract the package

cd kasm_release/
sudo ./install.sh
# Launch the installation script.
# During installation users will be prompted to create a swap partition if none are present.
# The Default usernames are admin@kasm.local and user@kasm.local.
# These users' passwords will be randomly generated and presented at the end of the install.

Kasm Workspaces. Installing applications.

In your web browser, navigate to https[:]//[IP address of your server]. Enter the admin login credentials, that it was previously generated by the installer script, when prompted, so you can log in to the Kasm admin interface

Kasm Workspaces allows administrators to define workspaces that users can use to access desktop environments, applications, or webpages directly to their web browsers. It is designed for remote access and virtualization, enabling users to access their workspaces without the need for traditional remote desktop software.

Each workspace and application runs in its own container, ensuring isolation and security, so you will be able to launch a variety of applications, links, tools, utilities, and even full distributions, from within a containerized environment. To install an application in Kasm Workspaces, navigate to the Workspaces section in the admin interface, you can edit existing Workspaces or add new Workspaces.

Kasm Workspaces

There are four types of workspaces that can be defined in Kasm Workspaces:

Kasm Workspaces

One of the cool features about Kasm is the number of workspaces that are available out of the box, e.g., browsers (Chrome, Brave, Edge, etc), Linux distributions (AlmaLinux, Fedora, Alpine, CentOS, etc.), office suites (LibreOffice, OnlyOffice), utilities (FileZilla), image editors (gimp, Pinta), etc. Using what Kasm calls the registry, you can chose from a catalog of Docker containerized services that can be used as the basis for a workspace.

Besides, you can add additional registries to Kasm: Workspaces, Registry, Registries, type the registry URL (e.g., https://kasmregistry.linuxserver.io/) and then click the Add Registry button.

Later on, you can select a workspace and edit various settings (most of them are self-explanatory):

{
  "hostname": "kasm",
   "user": "root"
}

An example would be (Docker Exec Config (JSON), Terminal Workspace): (the commands will run asynchronously of the terminal spinning up. Therefore, if you quickly try to run some of these commands, they will not found -just wait a few seconds.)

{
  "first_launch": {
    "user": "root",
    "cmd": "bash -c 'apt-get update && apt-get install -y iputils-ping && apt-get install -y nmap &&  apt-get install -y netcat &&  apt-get install -y bat &&  apt-get install -y neofetch &&  apt-get install -y tldr'"
  }
}

Web filtering

To set up web filtering, go to Settings, Web Filter on the left side of the screen. Click on Add Policy to create a new web filtering policy.

Give the policy a descriptive name and set it to Deny by Default if you want to maintain a very strict policy and block all websites except for the ones you or your company explicitly allow. To allow certain websites, add them to the white list by entering their URL in the Domain Whitelist field.

To block certain websites, add them to the blacklist by entering their URL in the Domain Blacklist field. Other than this, you should also enable the Safe Search option so that search engines could filter sites that they suspect contain malicious content.

Once you’ve set up your web filtering policy, go to Workspaces on the left side of the screen and select the Docker image (e.g., Chrome or Brave) you want to apply the copy, select Edit, scroll down to the Web Filter Policy field and select your previously created policy.

Using Kasm

When clicking on the “Workspaces” main button on the top next to “Admin” button you are presented with the Available Workspaces dashboard screen. Just click on one of them, it will prompt you to select how you want to open the session (in the current tab, new tab, or new window) and enjoy the ride! At any particular moment, click on the right arrow to access different options: log out, resume, pause, stop, and delete existing workspaces, clipboard (sharing between host and session), advanced settings, etc.

Audio is not supported on mobile browsers. Seamless Clipboard is only supported on Chrome and Chromium-based client browsers.

Installing via Scripting, Docker, and linuxserver.io

#!/bin/bash

# Variables
CTID=307                  # Container ID
OSTEMPLATE="ubuntu-24.10-standard_24.10-1_amd64.tar.zst"
TEMPLATE_STORAGE="local"  # Storage for the template
CONTAINER_STORAGE="mypool" # Storage for the container's disk
DISK_SIZE="80"            # Disk size in GB
PASSWORD="YOUR-PASSWORD" # Root password
HOSTNAME="kasm" # Hostname
MEMORY=4096              # Memory in MB (Docker needs more resources)
CORES=2                   # Number of CPU cores
BRIDGE="vmbr0"
IPADDRESS="192.168.1.88"      # Desired static IP
GATEWAY="192.168.1.1"         # Your LAN gateway
CIDR="/24"                    # Adjust if not 255.255.255.0

# 1. If container $CTID exists, remove it (optional)
if pct status $CTID &>/dev/null; then
	echo "Container $CTID exists. Stopping the container."
	pct stop $CTID
	sleep 2 # Giving it a moment to stop gracefully
	echo "Proceeding with deletion of container $CTID."
	pct destroy $CTID
else echo "Container $CTID does not exist."
fi

# 2. Download template if needed
# Check if the template is already downloaded
if ! pveam list $TEMPLATE_STORAGE | grep -q $OSTEMPLATE; then
  echo "Downloading Ubuntu template..."
  pveam download $TEMPLATE_STORAGE $OSTEMPLATE
else
  echo "Ubuntu template already exists."
fi

# 3. Create a privileged Ubuntu container
# Create the container with 80 GB disk on mypool
pct create $CTID $TEMPLATE_STORAGE:vztmpl/$OSTEMPLATE \
  --storage $CONTAINER_STORAGE \
  --rootfs $CONTAINER_STORAGE:$DISK_SIZE \
  --password $PASSWORD \
  --hostname $HOSTNAME \
  --memory $MEMORY \
  --cores $CORES \
  --net0 name=eth0,bridge=$BRIDGE,ip=$IPADDRESS$CIDR,gw=$GATEWAY \
  --unprivileged 0         # Set to 1 for unprivileged containers

pct set $CTID --onboot 0

# 4. Configure network interface with DHCP
# pct set $CTID --net0 name=eth0,bridge=vmbr0,ip=dhcp,firewall=0
# pct set $CTID --nameserver 8.8.8.8
# Setup a static IP via Cloud-Init (if you want):
# qm set $CTID --ipconfig0 ip=$IPADDRESS$CIDR,gw=$GATEWAY

# 5. Enable the "keyctl" feature (required for Docker) and Docker nesting features (if needed)
pct set $CTID --features nesting=1,keyctl=1,mknod=1

# (Optional) Unconfine AppArmor
touch /etc/pve/lxc/$CTID.conf
echo "lxc.apparmor.profile: unconfined" >> /etc/pve/lxc/$CTID.conf

# 6. Start container
pct start $CTID

# Wait a moment for container to boot
sleep 5

# 7. Install Docker inside the Ubuntu container
pct exec $CTID -- apt-get update
pct exec $CTID -- apt-get install -y docker.io

pct exec $CTID -- echo "root ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
pct exec $CTID -- echo "%sudo ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers


# Enable and start Docker
pct exec $CTID -- systemctl enable docker
pct exec $CTID -- systemctl start docker

# Test Docker
if ! pct exec $CTID -- docker --version; then
  echo "Docker installation failed. Exiting."
  exit 1
fi
echo "Test Docker"
pct exec $CTID -- docker run hello-world

# Check IP addresses
echo "Check IP addresses"
pct exec $CTID -- ip a

# Test Docker
echo "Test Docker"
pct exec $CTID -- docker run hello-world

# If you see an IP, test connectivity
pct exec $CTID -- ping -c 3 google.com

# 10. Finally run Kasm
# pct exec $CTID -- docker run --rm -it --shm-size=512m -p 6901:6901 -e VNC_PW="" kasmweb/ubuntu-focal-desktop:1.16.0
# User : kasm_user, Password: password
pct exec $CTID -- mkdir -p /etc/local.d

echo "Creating the startup-script.service"
pct exec $CTID -- bash -c "cat > /etc/systemd/system/startup-script.service << 'EOF'
[Unit]
Description=Startup Script to run Kasm Docker container
After=network.target docker.service

[Service]
Type=simple
ExecStart=/etc/local.d/mykasm-startup.sh

[Install]
WantedBy=multi-user.target
EOF"

pct exec $CTID -- bash -c "cat > /etc/local.d/mykasm-startup.sh << 'EOF'
#!/bin/bash
# Ensure Docker is running
while ! systemctl is-active --quiet docker; do
    echo 'Waiting for Docker...'
    sleep 1
done

# If container is already running, stop/remove it (optional)
docker rm -f kasm 2>/dev/null || true

# Run container in detached mode
docker run -d \
  --name=kasm \
  --privileged \
  -e KASM_PORT=443 \
  -p 3000:3000 \
  -p 443:443 \
  -v /mypool/kasm:/opt \
  --restart unless-stopped \
  lscr.io/linuxserver/kasm:latest

EOF"

pct exec $CTID -- chmod +x /etc/local.d/mykasm-startup.sh

pct exec $CTID -- systemctl daemon-reload
pct exec $CTID -- systemctl enable startup-script.service
pct exec $CTID -- systemctl start startup-script.service
# Output success message
echo "Ubuntu-based LXC container $CTID created with Docker installed."
echo "Kasm is running on https://$IPADDRESS:443/"
echo "User: kasm_user, Password: password"
pct exec $CTID -- ip a

Troubleshooting.

pveam available | grep ubuntu
system          ubuntu-20.04-standard_20.04-1_amd64.tar.gz
system          ubuntu-22.04-standard_22.04-1_amd64.tar.zst
system          ubuntu-24.04-standard_24.04-2_amd64.tar.zst
system          ubuntu-24.10-standard_24.10-1_amd64.tar.zst
root@myserver:~# pvesm status
Name             Type     Status           Total            Used       Available        %
local             dir     active        87531640        81797640         1409876   93.45%
local-lvm     lvmthin     active       148086784         3805830       144280953    2.57%
mypool        zfspool     active      7650410496       554518824      7095891672    7.25%

# Inside the container:
docker images | grep lscr.io
# If you see no matches, Docker never pulled the image.
# If pulling fails, you’ll see an error. You can also try a manual pull:
docker pull lscr.io/linuxserver/kasm:latest
# Then, run the container again:
docker run -d --name kasm ... lscr.io/linuxserver/kasm:latest

# Check all containers, including stopped ones:
docker ps -a

CONTAINER ID   IMAGE                                   STATUS                      NAMES
abcdef123456   lscr.io/linuxserver/kasm:latest         Exited (1) 10 seconds ago   kasm

# Then, the container started but immediately crashed or existed, so check its logs
docker logs kasm

FUSE allows user-space programs to create their own file systems without altering kernel code. TUN/TAP devices are virtual network devices that can be used to create a network interface. TUN is used for network packet tunneling, while TAP is used for network bridging.

lxc.mount.entry: /dev/fuse dev/fuse none bind,create=file 0 0
# It makes the FUSE device available inside the container
lxc.cgroup2.devices.allow: c 10:229 rwm
# It grants read, write, and mknod permissions for the FUSE device
lxc.mount.entry: /dev/net/tun dev/net/tun none bind,create=file 0 0
# It makes the TUN/TAP device available inside the containe
lxc.cgroup2.devices.allow: c 10:200 rwm
# It grants read, write, and mknod permissions for the TUN/TAP device.
[...]
pct reboot 307
# Enter the LXC Container and check:
ls -l /dev/fuse
ls -l /dev/net/tun
Bitcoin donation

JustToThePoint Copyright © 2011 - 2025 Anawim. ALL RIGHTS RESERVED. Bilingual e-books, articles, and videos to help your child and your entire family succeed, develop a healthy lifestyle, and have a lot of fun. Social Issues, Join us.

This website uses cookies to improve your navigation experience.
By continuing, you are consenting to our use of cookies, in accordance with our Cookies Policy and Website Terms and Conditions of use.