2017-01-18
Running X11 apps in an rkt container
rkt is a container runtime I've been using on a few projects recently. I was creating a container for Mozart which uses emacs as an IDE. This requires running an X11 application within the container and have it displayed on the host display.
To get this working I needed to mount my hosts X11 unix domain socket inside the container and provide an Xauthority
file that gave the container the rights to connect to the host X server.
The following shell commands use acbuild to create a container that runs xclock
as an example of the process:
acbuild begin docker://ubuntu:16.04
acbuild set-name bluishcoder.co.nz/xclock
acbuild run -- apt install --no-install-recommends --yes x11-apps
acbuild run -- rm -rf /var/lib/apt/lists/*
acbuild environment add DISPLAY unix$DISPLAY
acbuild environment add XAUTHORITY /root/.Xauthority
acbuild mount add x11socket /tmp/.X11-unix
acbuild mount add x11auth /root/.Xauthority
acbuild set-exec xclock
acbuild write --overwrite xclock.aci
acbuild end
It uses an Ubuntu Linux image from the Docker hub as a base and installs x11-apps
. To reduce disk space it removes cached package files afterwards. A DISPLAY
environment variable is set to point to use the same DISPLAY
as the host. The XAUTHORITY
enviroment variable is set to point to a file in the home directory of the root
user in the container.
The mount
subcommands expose the x11socket
and x11auth
endpoints to point to where the X11 unix domain socket and the Xauthority
file are expected to be. These will be provided by the rkt
invocation to mount host resources in those locations.
The final part of the script sets the executable to be xclock
and writes the aci
file.
On the host side we need to create an Xauthority
file that provides the container access to our X11 server. This file needs to be set so that any hostname can connect to the X11 server as the hostname for the container can change between invocations. To do this the authentication family in the file needs to be set to FamilyWild
. I got the steps to do this from this stack overflow post:
xauth nlist :0 | sed -e 's/^..../ffff/' | xauth -f myauthority nmerge -
This will retrieve the Xauthority
information for display :0
and modify the first four bytes to be ffff
. This sets the authority family to FamilyWild
. A new file called myauthority
is created with this data. This file will be mapped to the x11auth
mount point in the container.
The container can be executed with rkt
:
rkt run --insecure-options=image xclock.aci \
--volume x11socket,kind=host,source=/tmp/.X11-unix \
--volume x11auth,kind=host,source=./myauthority
The --volume
command line arguments map the mount points we defined in the acbuild
commands to locations on the host. The running xclock
application should now appear on the host X11 display.