Running GUI apps securely in docker (sandbox)

TechupBusiness
5 min readFeb 14, 2019

Docker is a fantastic tool when it comes to testing and running of command-line applications or whole new technologies. But when you need to run a GUI within the container, you’re stuck. Fortunately there are multiple solutions to address this issue. This article covers a quick tutorial to run GUI based Linux applications in docker, turning docker into a proper (but not 100% safe) sandbox.

Photo by Simone Viani on Unsplash (Partner of OST Simple Token)

The right approach

There are two options to transport the GUI data within docker to a client of your choice:

  1. Using VNC, a platform independent graphical desktop-sharing system. This option is useful for docker hosts without graphical user-interface (most Linux servers, like VPS or dedicated servers) OR if you use docker on operating systems without X server implementation. It is the most flexible and encapsulated option.
  2. Using X server, a windowing system for bitmap displays (common on Unix-based operating systems). This can be a very lean and elegant solution, as it is sharing the hosts GUI with the container’s OS.

Please be always aware that docker is not a perfect sandbox environment! If a program is designed to break out of a docker image and harm your host, there is an existing risk that this can be successful. But fortunately most (suspicious) applications are not designed (yet) to do this. Anyway, I would not recommend to watch trojans and viruses in docker containers. Just in case….

Prerequisite

First you need a host, having docker installed. Then, for option 1, make sure that you have docker-compose installed, which simplifies your docker life drastically.

Option 1: VNC — Flexible and secure on any host

This chapter explains the sandbox-setup using the first option “VNC”. Technically we are running a linux with desktop in docker and a VNC server, to connect with a VNC client to the server. This will work on ANY host operating system and offers a “strong” sandbox, which is theoretically more secure than a shared Xserver.

First create a new file calleddocker-compose.yml . Then paste the following content (and replace all <I-AM-A-PASSWORD> placeholder with your password) in it:

You can find more environment parameters on the projects’ github repository. We will use the Lightweight Qt Desktop Environment for our sandbox even though it is visually way less attractive than the standard gnome desktop. If you don’t care that much about hardware resources, simply remove -lxqt at the end of image version in dorowu/ubuntu-desktop-lxde-vnc:bionic-lxqt to enjoy the default Ubuntu gnome desktop.

Next step is to start the container. Type in your shell (you should be in the folder where the docker-compose.yml resides)

> docker-compose up -d

After the creation of the container, when it is up and running, you can start your VNC client to connect to your new instance (remember, you previously configured the password in docker-compose.yml as VNC_PASSWORD ).

Remmina: a VNC client on ubuntu to connect to our docker sandbox

Now you should see your running sandbox desktop:

Sandbox for ubuntu using Lightweight Qt Desktop Environment

For some reasons chromium (a browser) does not work. Instead you need to use the pre-installed Firefox.

IMPORTANT

Each time you delete your sandbox’s docker-container or when you change docker-compose.yml which triggers a recreation of the container, all your changes (apps, downloads, …) in your sandbox are lost! To keep important data, you must save it in /home/sandbox/shared, which is the only folder that is synced to your host and therefore persistent. For your host’s safety make sure not to save a harmful script in this folder.

Option 2: X server — Lean and integrated on hosts with GUI

This chapter explains the sandbox-setup using the second option “X server”. Here we are sharing the x server between our host and its containers to save hardware resources. As an extra security layer, to prevent malicious applications from accessing our host system and input, we will run an x server additional to our main GUI server.

The open-source project x11docker is in the end just a complex bash-script, which makes it easy to safely apply this special concept on docker. It would also support a VNC server approach. The main disadvantage of x11docker is, that it requires an additional workflow in comparison to a “standard-docker-architecture”. This prevents the use of docker-compose and is therefore harder to version control. It works for Linux (ideal) and Windows as well (with some limitations). As MacOS is not supported, please check the previous chapter of VNC as the way to go.

The fastest option to “install” it for the first time, is to execute in the shell:

> curl -fsSL https://raw.githubusercontent.com/mviereck/x11docker/master/x11docker | sudo bash -s -- --update 

Afterwards it is self-update-able by typing:

> sudo x11docker --update

To run the first sandbox (supporting also some windows applications using wine) we could run:

> x11docker --desktop x11docker/lxde-wine

IMPORTANT: To share some files between host and sandbox, x11docker can mount the home directory in the sandbox to the hosts home directory in ~/.local/share/x11docker/<IMAGENAME> by adding the parameter --home. All other changes in the sandbox will be lost when the docker-container is getting deleted.

> x11docker --desktop --home x11docker/lxde-wine

There are plenty of other options when running an image. The documentation page with all optional features, parameters and examples for an advanced usage can be found here.

Prepared sandbox

If you want to install some applications right away from the start, you can create your own docker image. Open a new file Dockerfile and add your command after a RUN prefix, like in the following example:

FROM x11docker/lxde-wine
RUN apt-get update
RUN apt-get install -y vlc

To use this new docker image with x11docker, you need to build and tag it, to easily run it by its name. Execute in the same folder where you placed the previous Dockerfile (replace <MY-NAME> with your desired image-name):

> docker build -t <MY-NAME> .

Now simply run your modified sandbox-image by executing:

> x11docker --desktop --home <MY-NAME>

That’s it. Now you can enjoy a better integrated docker-based sandbox. If you want to have a more native feeling and don’t care that much about security (e.g. when you trust the sandbox’ed applications) you can check out this chapter in x11docker documentation.

--

--