I've been using neovim-from-scratch as my IDE recently, and its incredibly brittle. This post takes some baby steps toward getting any desktop GUI app running in a docker container to run on my screen in Ubuntu 20.04. Eventually, I want to get this working on MacOS and using nvim, but for today we're trying to get any GUI application running on my screen in Ubuntu.
- X11 runs as server on the local users workstation
- Desktop applications run as clients, possibly on a remote machine
- X11 clients and server communicate over a TCP connection
Given this architecture, running a GUI inside in a docker container should be fine from X11 perspective. It's simply a matter of getting the correct networking setup and configuring the client to communicate with the X11 service.
The simplest path to something that works is to share the host network with the docker container. This is not the most secure and we can definitely do better. But doing so will require us to learn more about how X11 clients and servers communicate. The risk is that we could allow malicious applications to impersonate us on the internet by using our IP address and network location. Additionally, the dockerized application could access anything on our own machine over the network. Longer term, locking down to minimum number of X11-specific ports should stop these risks.
To tell docker run a container with host networking we do:
docker run --net host ...
Pointing our client application at the X11 Server
X11 clients read the
DISPLAY environment variable to discover the X Server.
DISPLAY generally takes the form:
<hostname>:<display number>. The default value is typically
:0 -- meaning use display 0 on the localhost. However, on my machine I see
DISPLAY is set to a higher number. The easiest way to make sure the docker container has the correct
DISPLAY value is to pass that variable from the host to the container:
docker run -e DISPLAY
We'll use the xeyes application as a simple test that things are working. A docker image exists for this at
Testing It Out
Let's open a terminal and do this:
docker run --rm -ti --net=host -e DISPLAY fr3nd/xeyes
If all is well, you should see some crazy eyes in a window following your mouse around. Success!
Now to put a cherry on top, we'd like to create a desktop icon we can use to launch the crazy eyes application without doing arcane docker magic. After much fumbling, I've discovered this magic:
[Desktop Entry] Version=1.0 Type=Application Terminal=false Exec=/usr/bin/docker run --rm --net=host -e DISPLAY fr3nd/xeyes Name=xeyes
Save the above inside
xeyes.desktop on your desktop. You'll also need to right-click on this icon and choose "Allow Launching" before this will work. Double click the icon and you should see the same crazy eyes appear!
- Tested on Ubuntu 20.04 LTS -- results may vary on other versions of Ubuntu
- docker run must not contain
-itor else you must use a terminal which is very annoying
- The full path to docker without any
~must be set in
DISPLAYwill only work like this because we're running Linux inside and outside the container on the same machine with shared networking. Don't expect this value of
DISPLAYto work on MacOS