DEV Community

Cover image for Running graphic apps in Docker: AWS WorkSpaces
Axel Navarro for Cloud(x);

Posted on

Running graphic apps in Docker: AWS WorkSpaces

As a Linux user, I need to connect to an Amazon WorkSpace but the client app can only be run in specific old, but maintained, versions of Ubuntu. I've tried with the latest Ubuntu version but it haven't worked, so created a virtual machine with Ubuntu Focal 20.04 but this setup used 14GB of disk space 😵 only to open a window application. This didn't make any sense and also included issues when sharing the clipboard from the host to the VM and then to the virtual desktop hosted in Amazon. 🙄
Then, I remembered that we can run graphic applications using Docker. Let's see how to connect a container to the host's X Window System.

Creating the Docker image

The following Dockerfile builds the image using Ubuntu Focal 20.04, and installs the Amazon WorkSpace client:

FROM ubuntu:focal

ENV DEBIAN_FRONTEND=noninteractive

RUN apt update && \
  apt install -y libusb-1.0-0 wget xauth && \
  wget -q -O - https://workspaces-client-linux-public-key.s3-us-west-2.amazonaws.com/ADB332E7.asc | apt-key add - && \
  echo "deb [arch=amd64] https://d3nt0h4h6pmmc4.cloudfront.net/ubuntu focal main" > /etc/apt/sources.list.d/amazon-workspaces-clients.list && \
  apt remove -y wget && \
  apt update && \
  apt install -y workspacesclient && \
  touch /root/.Xauthority && \
  rm -rf /var/lib/apt/lists/*
Enter fullscreen mode Exit fullscreen mode

💡 libusb-1.0-0 is a dependency of Amazon WorkSpaces.

The DEBIAN_FRONTEND=noninteractive environment is used to skip the Ubuntu’s prompt asking for our time zone.

Build the image with the following command:

docker build -t workspace .
Enter fullscreen mode Exit fullscreen mode

The Docker image's size is 1.2GB, a reduction of 91% in comparison to the 14GB of the virtual machine.

Starting the container

Now, we can run the container!

docker run --name ws --network=host -e DISPLAY -v /tmp/.X11-unix -it workspace
Enter fullscreen mode Exit fullscreen mode

We need to share the .X11-unix/ directory where the connection socket is located, where DISPLAY is the name of the host's display.

The --network=host argument makes the container use the same host's network so the container does not get its own IP address. This avoids the container being network isolated. 🪛

Starting the GUI application

Before starting the app we must authenticate the X Window System of the container with the host.

Get the authorization entry of the host using the xauth command:

xauth list
Enter fullscreen mode Exit fullscreen mode

Copy the output of the command and run this in the container (replacing the placeholders with the values from the clipboard):

xauth add <display_name> <protocol_name> <hex_key>
Enter fullscreen mode Exit fullscreen mode

Now you are able to start GUI applications inside the container! 🎉

/opt/workspacesclient/workspacesclient
Enter fullscreen mode Exit fullscreen mode

Alternative: use VNC instead of X11

We need to make a few changes to run a VNC server in the container:

FROM ubuntu:focal

ENV DEBIAN_FRONTEND=noninteractive

RUN apt update && \
  apt install -y libusb-1.0-0 gpg wget x11vnc xvfb && \
  wget -q -O - https://workspaces-client-linux-public-key.s3-us-west-2.amazonaws.com/ADB332E7.asc | apt-key add - && \
  echo "deb [arch=amd64] https://d3nt0h4h6pmmc4.cloudfront.net/ubuntu focal main" > /etc/apt/sources.list.d/amazon-workspaces-clients.list && \
  apt remove -y wget && \
  apt update && \
  apt install -y workspacesclient && \
  rm -rf /var/lib/apt/lists/*

RUN echo "exec /opt/workspacesclient/workspacesclient" > ~/.xinitrc && \
  chmod +x ~/.xinitrc

CMD ["x11vnc", "-create", "-forever"]
Enter fullscreen mode Exit fullscreen mode

The x11vnc command will start an X11 session in the container launching the application specified in the ~/.xinitrc file.

docker build -t workspace .
Enter fullscreen mode Exit fullscreen mode

Then, we can run the container:

docker run --name ws -it workspace
Enter fullscreen mode Exit fullscreen mode

But how can we know the IP address of the container? Just check it with the following command:

docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' ws
Enter fullscreen mode Exit fullscreen mode

Now you can connect to the VNC server. 🔌

Conclusion

We can run graphic applications that work in specific Linux distros using Docker 🐋, by connecting directly to our X Window System. This uses less memory and disk space than a VM.

You can get the same in Windows as the host using Xming.

xauth could be used in conjunction with SSH to run remote GUI apps 😉 in our local, but that's for another post.

Alternatively, you can start a VNC server in a container allowing more flexibility either if you use macOS, or if you can't connect using X11 because you're using Wayland. But this doesn't feel like a native window on your OS.

Latest comments (0)