The first principle is that you must not fool yourself – and you are the easiest person to fool, Richard Feynman

In this tutorial, we’ll walk through building a fully customized Docker image for Kasm Workspaces, starting from the official Ubuntu Core base maintained by Kasm Technologies.
You’ll learn how to:
|
—Dockerfile
This is the file where you define the steps to build your custom Docker image. It includes instructions like which base image to use, which files to copy, and which commands to run for system configurations and software installations.
—runlocally.sh
A shell script to automate the build process and run the image locally for testing purposes.
—— build
This directory contains additional resources, configuration files, or files that you want to include in your Docker image.
———wallpaper.png
# An image file, which could be used as a background image for workspace customization.
———starship.toml
# Configuration file for Starship, enabling a customizable cross-shell command prompt.
———terminator.toml
# Configuration file for Terminator, a versatile terminal emulator.
# =============================================================================
# KASM Ubuntu Focal Desktop with Custom Enhancements
# =============================================================================
# Base image: Ubuntu 20.04 LTS with KASM VNC desktop environment
# This creates a containerized desktop environment accessible via web browser
FROM kasmweb/ubuntu-focal-desktop:1.16.0-rolling
# Rolling tags are images that are updated and built nightly to ensure your images are running the latest version.
# Switch to root for system-level installations
USER root
# =============================================================================
# ENVIRONMENT VARIABLES
# =============================================================================
ENV KASM_VNC_CLIPBOARD=false \
HOME=/home/kasm-default-profile \
STARTUPDIR=/dockerstartup \
INST_SCRIPTS=$STARTUPDIR/install \
STARSHIP_CONFIG=/home/kasm-user/.config/starship.toml
# Set working directory to user home
WORKDIR $HOME
# =============================================================================
# SYSTEM PACKAGES INSTALLATION
# =============================================================================
# Install essential applications and utilities in a single layer to minimize image size
RUN apt-get update && \
apt-get -y upgrade && \
apt-get -y install --no-install-recommends \
# VPN and networking
openvpn \
# Package management
gdebi \
synaptic \
# Multimedia applications
gimp \
vlc \
# Office suite
libreoffice \
# Security tools
keepassxc \
# System utilities
unzip \
ca-certificates \
wget \
# Desktop environment components
dbus-x11 \
xfconf \
# Fonts for better text rendering
fonts-roboto \
fonts-cascadia-code \
fonts-firacode \
# UI theme
numix-gtk-theme \
&& \
# Clean up package cache to reduce image size
apt-get clean && \
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
# =============================================================================
# DESKTOP CUSTOMIZATION
# =============================================================================
# Set custom wallpaper
# The background can be changed by overwriting the /usr/share/backgrounds/bg_default.png file.
COPY config/wallpaper.png /usr/share/backgrounds/bg_default.png
# =============================================================================
# STARSHIP PROMPT INSTALLATION
# =============================================================================
# Download and install Starship (modern shell prompt)
RUN wget -O install.sh https://starship.rs/install.sh && \
chmod +x install.sh && \
./install.sh --yes && \
rm -f install.sh
# Configure Starship for bash shell
RUN echo 'eval "$(starship init bash)"' >> /home/kasm-default-profile/.bashrc
# =============================================================================
# FONT INSTALLATION
# =============================================================================
# Install Hack Nerd Font for better terminal experience
RUN wget -O hack-font.zip https://github.com/ryanoasis/nerd-fonts/releases/download/v3.1.1/Hack.zip && \
unzip hack-font.zip -d /usr/local/share/fonts/ && \
fc-cache -fv && \
rm -f hack-font.zip
# =============================================================================
# USER DIRECTORY SETUP
# =============================================================================
# Create necessary directories for both user profiles
RUN mkdir -p /home/kasm-user/.config \
/home/kasm-user/.config/autostart \
/home/kasm-default-profile/.config && \
chown -R 1000:0 /home/kasm-user /home/kasm-default-profile
# =============================================================================
# CONFIGURATION FILES
# =============================================================================
# Copy Starship configuration to both user profiles
COPY config/starship.toml $STARSHIP_CONFIG
COPY config/starship.toml /home/kasm-default-profile/.config/starship.toml
# =============================================================================
# SYSTEM FIXES AND OPTIMIZATIONS
# =============================================================================
# Fix VNC startup script to handle process termination gracefully
RUN sed -i.bak '/^ *kill /s/$/ 2>\/dev\/null || true/' $STARTUPDIR/vnc_startup.sh
# Set proper permissions for the home directory
RUN chown -R 1000:0 $HOME && \
$STARTUPDIR/set_user_permission.sh $HOME
# =============================================================================
# USER-LEVEL CONFIGURATIONS
# =============================================================================
# Switch to non-root user for user-level configurations
USER 1000
WORKDIR /home/kasm-user
# Create autostart entry for Numix theme activation
RUN cat << 'EOF' > .config/autostart/numix-theme.desktop
[Desktop Entry]
Type=Application
Name=Numix Theme Activator
Comment=Applies Numix theme on desktop startup
Exec=sh -c "xfconf-query -c xsettings -p /Net/ThemeName -s Numix && xfconf-query -c xsettings -p /Net/IconThemeName -s Numix"
NoDisplay=true
X-GNOME-Autostart-enabled=true
StartupNotify=false
EOF
# =============================================================================
# FINAL PERMISSIONS SETUP
# =============================================================================
# Ensure all user files have correct ownership
USER root
RUN chown -R 1000:0 /home/kasm-user /home/kasm-default-profile
# Switch back to non-root user for security
USER 1000
Step 1. Build your custom Docker image: docker build -t nmaximo7/myctperdocker:latest .
nmaximo7/myctperdocker:latest.Step 2. To run this custom image in a local environment start the docker container with the following command, and connect to your machine on https://localhost:6901 and log in with username kasm_user and password password.
docker run –rm -it \
–shm-size=512m \
-p 6901:6901 \
-e VNC_PW=password \
-e KASM_VNC_CLIPBOARD=false \
nmaximo7/myctperdocker:latest
Error: KasmVNC encountered an error, clipboard read, value of name member of PermissionDescriptor is not a valid value for enumeration PermissionName. This is a known bug specific to Firefox. You could try using a different browser (e.g., Chrome) where the bug might not manifest.
docker run starts a new container from the built image.
‐‐rm automatically removes the container when it exits.
-it allows you to interact with the container via the command line (interactive terminal).
‐‐shm-size=512m allocates 512 megabytes of shared memory for the container.
-p 6901:6901 maps port 6901 on your host to port 6901 on the container, making it accessible from your host machine.
-e VNC_PW=password sets an environment variable VNC_PW inside the container with the value password, used for VNC access.
-e KASM_VNC_CLIPBOARD=false disables clipboard sharing in the VNC session.
nmaximo7/myctperdocker:latest specifies the image to use (nmaximo7/myctperdocker) and the tag (latest), which typically points to the most recent version of the image.
Step 3. Next, connect to your machine on https://localhost:6901 and log in with username kasm_user and password password.

#!/bin/bash
# Shebang. It specifies that the script should be run using the Bash shell.
docker build -t nmaximo7/myctperdocker:latest .
# It builds a Docker image from the current directory (.) and tags it as nmaximo7/myctperdocker:latest
docker run --rm -it \
--shm-size=512m \
-p 6901:6901 \
-e VNC_PW=password \
-e KASM_VNC_CLIPBOARD=false \
nmaximo7/myctperdocker:latest
# Starts the new container from the built image.
sleep 2
# Pauses the script for 2 seconds, giving the container time to start up and become ready.
google-chrome-stable https://localhost:6901
# Launches Chrome and navigates to the VNC interface available at localhost:6901.
There are several ways to remove all Docker containers, depending on whether you want to remove only stopped containers or all containers (including running ones).
docker rm $(docker ps -aq).
docker ps -aq: Lists all container IDs (-a for all containers, -q for quiet mode, which outputs only IDs). docker rm: Removes the containers specified by the IDs returned by the previous command.
docker rm -f $(docker ps -aq). The flag -f stands for “force”, which forces the removal of running containers without stopping them first.❯ docker ps # Find the Container ID
❯ docker stop [CONTAINER_ID] # Stop the container using its ID
To push your Docker image to Docker Hub, follow these steps:
First, you need to create an account on Docker Hub.
Open your terminal and log in to Docker using the command:
nmaximo7 on nixos customdocker/myctperdocker/ubuntuxfc on main [✘!?]
❯ docker login
# Introduce your Docker Hub credentials
nmaximo7 on nixos customdocker/myctperdocker/ubuntuxfc on main [✘!?] took 4s
Push your Docker image to Docker Hub.
❯ docker push nmaximo7/myctperdocker:latest
# It uploads your image tagged as latest to your Docker Hub repository.
To register your Docker image in Kasm, create a new Workspace as follows:
Container.My Custom Container.nmaximo7/myctperdocker:latest.https://index.docker.io/v1/.By following these steps, you can successfully push your Docker images to Docker Hub and register them for use in Kasm.