Docker is all the rage these days, with its simple and elegant way to package applications and even entire systems into something that can be ran on any Linux host with Docker installed. But what if Docker could be extended to desktop applications?
That would open up all kinds of new use cases for containerization. This is where Kasm and KasmVNC come in. Kasm is a new containerized desktop infrastructure (CDI) solution while KasmVNC is the open source core that provides the rendering of the containerized desktop environment. Kasm is 100% web based on the front-end with no software to install for clients.
This blog will walk you through how to implement UI streaming using nothing but open source and then the full Kasm stack. The benefit of using the full Kasm stack is scalability, ease of management, and enterprise features like SAML and LDAP authentication, logging, persistent profiles, and more. Kasm has a community edition, which has all the same features as the paid, but is limited to 5 concurrent users.
As a test, we will be containerizing Doom. What better way to demonstrate the containerization of UI applications than killing daemons in this 1990s classic first person shooter.
Disclaimer: I am co-founder of Kasm Technologies and the KasmVNC open source project.
Open Source Route
Who doesn’t like a fully open source solution to a problem? It is completely possible to implement much of what Kasm does using our open source KasmVNC and the docker image examples we provide.
The KasmVNC GitHub page provides the Doom example right in the code repository https://github.com/kasmtech/KasmVNC/tree/master/docker.
git clone https://github.com/kasmtech/KasmVNC.git cd KasmVNC/docker sudo docker build -t kasm/doom -f Dockerfile.ubuntu18.doom . sudo docker run -it -p 443:8443 — rm -e “VNC_USER=matt” -e “VNC_PW=password123” kasm/doom:latest
Now navigate to https://<your-ip>
Ok, that was too easy, lets break down that dockerfile and see what is going on…
FROM ubuntu:18.04 ENV DISPLAY=:1 VNC_PORT=8443 MAX_FRAME_RATE=24 VNCOPTIONS="-PreferBandwidth -DynamicQualityMin=4 -DynamicQualityMax=7" HOME=/home/user TERM=xterm STARTUPDIR=/dockerstartup INST_SCRIPTS=/dockerstartup/install KASM_RX_HOME=/dockerstartup/kasmrx DEBIAN_FRONTEND=noninteractive VNC_COL_DEPTH=24 VNC_RESOLUTION=640x480 VNC_PW=vncpassword VNC_USER=user VNC_VIEW_ONLY_PW=vncviewonlypassword LD_LIBRARY_PATH=/usr/local/lib/ OMP_WAIT_POLICY=PASSIVE SHELL=/bin/bash SINGLE_APPLICATION=1 EXPOSE $VNC_PORT WORKDIR $HOME ### REQUIRED STUFF ### RUN apt-get update && apt-get install -y supervisor xfce4 xfce4-terminal xterm libnss-wrapper gettext libjpeg-dev wget RUN apt-get purge -y pm-utils xscreensaver* RUN mkdir -p $STARTUPDIR COPY src/startup/ $STARTUPDIR RUN mkdir -p $HOME/.config/xfce4/xfconf/xfce-perchannel-xml COPY src/xfce/ $HOME/.config/xfce4/xfconf/xfce-perchannel-xml # overwite default with single app config RUN mv $HOME/.config/xfce4/xfconf/xfce-perchannel-xml/xfce4-desktop-single-app.xml $HOME/.config/xfce4/xfconf/xfce-perchannel-xml/xfce4-desktop.xml RUN echo 'source $STARTUPDIR/generate_container_user' >> $HOME/.bashrc # KasmVNC install RUN wget -qO- https://github.com/kasmtech/KasmVNC/releases/download/v0.9.1-beta/KasmVNC_0.9.1-beta_Ubuntu_18.04.tar.gz | tar xz --strip 1 -C / RUN cp /usr/local/share/kasmvnc/www/vnc.html /usr/local/share/kasmvnc/www/index.html ### START CUSTOM STUFF #### # We need the server to use a fixed resulution and have the client scale, which is not the default behavior of KasmVNC RUN sed -i "s#UI.initSetting('resize', 'remote');#UI.initSetting('resize', 'scale');#" /usr/local/share/kasmvnc/www/app/ui.js RUN apt-get install -y chocolate-doom doom-wad-shareware prboom-plus freedoom # Use software rendering, comment this out if you have a GPU #RUN mkdir -p $HOME/.local/share/chocolate-doom && # echo 'force_software_renderer 1' > $HOME/.local/share/chocolate-doom/chocolate-doom.cfg ### END CUSTOM STUFF ### RUN chown -R 1000:0 $HOME USER 1000 WORKDIR $HOME ENTRYPOINT [ "/dockerstartup/vnc_startup.sh", "xfce4-terminal", "-e", "/usr/games/chocolate-doom" ]
We are interested in a few environmental variables up top. Any of these can be overridden at run time, you can see in the docker run example we over wrote the username and password used for KasmVNC. The VNC_PW environmental variable is unset during startup, so your password is not kept in that variable at runtime. Another environmental variable of interest is the last one SINGLE_APPLICATION, which will get rid of the desktop and just display the single app in the KasmVNC webpage.
After that is the required stuff, which is the installation of a desktop environment, KasmVNC, and copying over configurations and scripts. The meat of what you need is after the “START CUSTOM STUFF HERE” comment. You can see that doom is installed. Just before that you see a sed command, this is changing the KasmVNC web page to default to client scaling, which locks the server into the configured resolution.
By default KasmVNC automatically scales the server side resolution as the client resolution changes, which is not advantageous for this example, but for most desktop applications is highly preferred. So, you may want to comment that line out for your specific use case.
Finally, the ENTRYPOINT, needs to be customized. It needs to have /dockerstartup/vnc_startup.sh first, followed by commands and arguments for your application. To get Doom to work for me, I had to open an xfce4-terminal first and execute Doom from there. In most situations you would likely just execute the GUI application directly.
Full Kasm Stack
Running Doom inside a streaming container is cool, but what if we had an enterprise use case for streaming UI containers to a bunch of users and needed stuff like SAML authentication, logging, performance metrics and analytics, audio in and out, and all that nice commercial grade gravy. That’s where Kasm comes in. Kasm is available in Community Edition, Professional, and Enterprise and can run in the cloud as a SaaS, on-premise, or in a hybrid configuration.
Kasm actually open sources examples of how to create your own Kasm compatible docker images, to include single applications. Here is a link to the Chrome Container:
Kasm installation on a single server deployment is very easy, full details can be found here:
The short of it is, install docker, download the kasm release tar file and run a few commands. The installation will download the base images, so it will take about 10 minutes to install depending on the speed of your internet.
wget https://kasm-static-content.s3.amazonaws.com/kasm_release_1.7.0.a80105.tar.gz tar -xzvf kasm_release_1.7.0.a80105.tar.gz sudo bash kasm_release/install.sh
If you are running on a cloud VM with no swap, you will get a warning, just press y to continue. At the end of the installation it will list all the credentials, which are randomly generated during the install. Navigate to the web page https://<ip-address> and login as [email protected] using the password provided.
Next go to Users and click the key icon next to the [email protected] user and change the password.
Custom Kasm Image
The custom Kasm image is slightly different then the open source version. Create a file dockerfile.doom with the following contents.
FROM kasmweb/core:1.7.0 USER root ENV HOME /home/kasm-default-profile ENV STARTUPDIR /dockerstartup ENV INST_SCRIPTS $STARTUPDIR/install WORKDIR $HOME ######### Customize Container Here ########### # Install Doom RUN apt-get install -y chocolate-doom doom-wad-shareware prboom-plus freedoom # Enabled Single Application Mode - No desktop environment will be spawned RUN wget -O $HOME/.config/xfce4/xfconf/xfce-perchannel-xml/xfce4-desktop.xml https://bitbucket.org/kasmtech/kasm_release/raw/44c6c00e086649f54e8b2756601f710dbca89805/src/common/install/kasm/xfce_settings/xfce4-desktop-single-app.xml ENV SINGLE_APPLICATION=1 RUN apt-get remove -y xfce4-panel RUN echo 'xfce4-terminal -e /usr/games/chocolate-doom' > $STARTUPDIR/custom_startup.sh RUN chmod +x $STARTUPDIR/custom_startup.sh ######### End Customizations ########### RUN chown 1000:0 $HOME RUN $STARTUPDIR/set_user_permission.sh $HOME ENV HOME /home/kasm-user WORKDIR $HOME RUN mkdir -p $HOME && chown -R 1000:0 $HOME USER 1000
Now we can build our Doom Kasm.
sudo docker build -t kasmweb/doom:1.7.0 -f dockerfile.doom .
Next log into Kasm as an administrator and navigate to Images. Click “Create New Image” in the upper right corner. Fill in the details as shown in this screenshot, feel free to provide a thumbnail image, but it is not require. This is a locally built image, so be sure to leave the Docker Registry details empty.
- Name — Must be the docker image name kasmweb/doom:1.7.0
- Description — Anything you want
- Friendly Name — The name displayed to users
- Thumbnail URL — The image to display to users, here I used the image from wikipedia
- Cores — The number of cores to allow for this image. Two seems adequate but you might get away with one if you have a good CPU.
- RAM — In my testing 1.7GB was plenty of RAM to explore the underworld
Click save and go back to User->Kasm and you will see the image available to create.
Click Create, now you can enjoy Doom with audio, share the session with other users, and start your own Doom SaaS.