Extending Google Cloud Workstations containers to run any GUI based program
Are you having difficulty customizing Google Cloud Workstations to run a GUI program outside of the supported configurations of IDE’s?
If so, you’re not alone. In this article we discuss how to use the base Docker image and build it to run terminal and Google Chrome.
Before we start, it is essential to know how to set-up a Workstation Configuration. Here is a resourceful guild to get yourself familiar with the user interface of setting up a cluster and configuration.
Extending the base images
To customize the Cloud Workstation, we will be using the preconfigured base image. You can also use the preconfigured IDE images to extend your use case. In this case we will need the following files:
Dockerfile
xpra-xterm.sh
The base image does not have an IDE installed. In our specific use case, the GUI program we would be using is: Google Chrome, and xterm. The command line TCP debugging tools would be: curl and tcpdump. Here are the structure of the two files.
Dockerfile:
FROM us-central1-docker.pkg.dev/cloud-workstations-images/predefined/base
# Install Xpra
RUN curl http://xpra.org/gpg.asc > /etc/apt/keyrings/xpra.asc && \
echo "deb [signed-by=/etc/apt/keyrings/xpra.asc] http://xpra.org/ noble main" > \
/etc/apt/sources.list.d/xpra.list && \
apt-get update && apt-get install -y \
xpra \
xpra-x11 \
xpra-html5 \
python3-requests \
python3-paramiko \
python3-zeroconf \
python3-avahi
# Install curl CLI
RUN apt-get install -y curl --no-install-recommends
# Install tcpdump CLI
RUN apt-get install -y tcpdump
# Install google-chrome
RUN wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb && \
apt-get update && \
apt install -y ./google-chrome*.deb && \
rm google-chrome*.deb && \
apt-get clean && \
rm -rf /var/lib/apt/lists/* && \
# Ensure chrome will work in a headless environment without gpu support by
# specifying environment variables and flags
echo "QT_X11_NO_MITSHM=1 _X11_NO_MITSHM=1 _MITSHM=0 $(tail -n -1 /opt/google/chrome/google-chrome) --disable-gpu --disable-dev-shm-usage --use-gl=swiftshader" >> /opt/google/chrome/google-chrome && \
sed -i 'N;$!P;D' /opt/google/chrome/google-chrome
# Clean up apt package lists
RUN apt-get clean && rm -rf /var/lib/apt/lists/*
# create xpra-xterm shortcut for upstart
COPY ./xpra-xterm.sh /etc/workstation-startup.d/110_start-base-xterm.sh
xpra-xterm.sh
#!/bin/bash
runuser user -c -l "xpra start --bind-tcp=0.0.0.0:80 --min-port=80 --html=on --systemd-run=yes --daemon=no --dbus-launch= --dbus-control=no --start-child-after-connect=xterm"
For the custom Cloud Workstation to run properly, we need to use Xpra. Users are able to interact with google-chrome or X Windows server running in an X11 session that can be accessed via the Xpra html server/client. Google Chrome needs to be configured to run as headless and without gpu support.
By using a customized container base image, we need to configure the startup environment of the container to execute Xpra with xterm as a start-up script. In this specific case we are using an additional executable shell script under /etc/workstation-startup.d/xpra-xterm.sh
to customize the running container.
You might ask what is this program: xterm? It is also referred to as “terminal” it is the default Debain GUI shell application to run command line functions.
Structure of start-up shell script
- The command
runuser user -c -l
, makes sure that when X11 — Xpra runs as the user with interactive login. This is to ensure Google Chrome and other GUI based programs does not run as the default Docker root user. - The command
xpra start --bind=0.0.0.0:80 --min-port=80 --html=on --systemd-run=yes --daemon=no --dbus-launch --dbus-control=no --start-child-after-connect=xterm
, sets Xpra to listen to port: 80. When the container is started, it will run as upstart script (using systemd) without functioning as a system daemon background process. The GUI program: terminal, will only start after connecting to the Cloud Workstation.
Deploying and connecting to the custom image
To deploy the Docker image, you first would need to build your container and deploy to Artifact Registry. Once the image is uploaded to Artifact Registry, you would need to select the Custom container image from the Environment settings in the create workstation configuration set-up page:
To launch the Workstation and xterm after creating the configuration and workstation, select the Launch button in Cloud Console:
Another tab will open with a connection to the default workstation URL format:
https://PORT-WORKSTATION_NAME.CLUSTER_ID.cloudworkstations.dev
From there you will have the terminal command: xterm, as the single GUI program running.
In the terminal you can run the command to start-up Google Chrome: google-chrome
Summary
Google Cloud Workstations offers a powerful solution for developers by providing managed, secure, and customizable cloud-based development environments. This approach standardizes setups across teams and removes the burden of local machine configuration.
This guide details the practical steps for deploying a barebone GUI application and CLI programs such as: curl and tcpdump. For more examples of customizations, check out the Google Cloud GitHub for other custom image examples. Also don’t forget about security best practices.