Running Desktop Applications on Containers

Docker is an important tool for running web applications in both production and development environments nowadays. Actually, it can also be used for running desktop applications. That means you can take advantage of Docker's mobility even on the desktop. However, there are some tricks to make that work well. In short, you have to enable applications inside containers to use some resources on the host machine.

Using X11 via Unix Socket

As you may know, X11 originally supports remote use and it can be accessed via TCP or Unix Domain sockets. To use this function via Unix socket, mount /tmp/.X11-unix directory with docker's --volume (-v) option.

docker run -v /tmp/.X11-unix ...

Note that remote access from the container to the host machine must be allowed. xhost(1) is a convenient interface for tweaking access control. The following command makes the X11 server on the host machine accept access from remote user on containers.

xhost +"local:docker@"

Using Video/Audio Resources on Host

Some devices are required on containers to use speakers, microphones, and webcams on the host machine. /dev/snd directory includes ALSA device files which are mandatory to play sounds. Webcam device files can be accessed by /dev/video* files.

To make the Video/Audio work, mounting these files might not be enough. The files under /dev/snd directory are owned by root user and audio group and the files /dev/video* are owned by root user and video group. That is to say, if you run an application as an ordinary user which does not have UID 0 (= root user on the host), the user must belong to the audio and video group on the host OS.

docker run 	\
  --device /dev/snd \
  --device /dev/video0 \
  --group-add $(getent group audio | cut -d: -f3) \
  --group-add $(getent group video | cut -d: -f3) \
  ...

--group-add option takes either group names or GIDs. The important thing is you have to pass the host's groups. GIDs may be different even though a group name is the same between the host OS and containers. That is why in this case you should pass GID, but not the group name.

Allowing System Calls

Docker disables some system calls by default using Seccomp. By the way, some applications (such as Google Chrome) use system calls which are disabled by default. To allow them, create custom Seccomp profiles. The default Docker profile can be found here:

https://github.com/moby/moby/blob/master/profiles/seccomp/default.json

Using the Network Stack on Host

If you develop web applications, --network option may be useful. Docker creates and uses a dedicated network stack by default (bridge). In other words, a web application running on http://localhost:3000 cannot be opened by web browsers on these containers as they're in different networks. In such a case, you can pass the --network=host option which makes containers use the host's network stack.

Gentaro "hibariya" Terada

Otaka-no-mori, Chiba, Japan
Email me

Likes Ruby, Internet, and Programming.