Running GUI apps in Docker containers

This is a little guide to run GUI apps in Docker containers on top of a OSX (Docker for Mac)

First of all make sure you have Docker for Mac installed. Once running you should have on the top right corner a Docker icon.

Image for post
Image for post
Docker for Mac installation

XQuartz

Since Mac doesn’t come with X11 so we’ll use XQuartz to do the X11 forwarding.

Let’s install it using Homebrew:

brew install Caskroom/cask/xquartz

Once installed logout and login again. This is important otherwise the remote connections will fail to X11.

Let’s launch XQuartz

open -a Xquartz

Run xterm (The tools of Xquartz will be found at “/opt/X11/bin”)

/opt/X11/bin/xterm
Image for post
Image for post
Xterm Instance

Ok, now we launched a Terminal on the X11, using local DISPLAY, let’s get a bit closer to what we’ll do with containers and launch it remotely. Get the local IP address, export it in DISPLAY and launch xterm

ip=$(ifconfig | sed -En 's/127.0.0.1//;s/.*inet (addr:)?(([0-9]*\.){3}[0-9]*).*/\2/p')
export DISPLAY=$ip:0
/opt/X11/bin/xterm

Now you got xterm running remotely on your machine but there is a catch, xQuartz knows you’re not actually remotely and permits you to open connections, if you try it from the container it will still fail.

In order to test this before trying with the container, let’s try to launch xterm with root user (NOTE: It is never safe to run GUI apps with root user, this is just to test connection)

sudo su -
ip=$(ifconfig | sed -En 's/127.0.0.1//;s/.*inet (addr:)?(([0-9]*\.){3}[0-9]*).*/\2/p')
export DISPLAY=$ip:0
/opt/X11/bin/xterm

You’ll get the following error

No protocol specified
Warning: This program is an suid-root program or is being run by the root user.
The full text of the error or warning message cannot be safely formatted
in this environment. You may get a more descriptive message by running the
program as a non-root user or by removing the suid bit on the executable.
/opt/X11/bin/xterm: Xt error: Can't open display: %s

To fix this you’ll need to do two things

Allow connections from network clients

Select XQuartz menu, go to Preferences and Check “Allow connections from network clients”

Image for post
Image for post
XQuartz Preferences

This will allow remote connections, but you also need to white-list the ip:

ip=$(ifconfig | sed -En 's/127.0.0.1//;s/.*inet (addr:)?(([0-9]*\.){3}[0-9]*).*/\2/p')
echo $ip
/opt/X11/bin/xhost + $ip

Now if you try again running the xterm you’ll be able to get a terminal.

Run GUI Apps

Now that we got a X11 configured on our OSX, let’s run firefox inside a container:

docker run -i -e DISPLAY=$ip:0 jess/firefox
Firefox inside Docker
docker run -i -e DISPLAY=$ip:0 jess/spotify
Image for post
Image for post

For more GUI examples see: https://github.com/jessfraz/dockerfiles

Written by

Docker Captain, Google Developer Expert & Founder of Harbur Cloud Solutions (https://harbur.io)

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store