How can you run GUI applications in a Docker container?
Are there any images that set up vncserver
or something so that you can - for example - add an extra speedbump sandbox around say Firefox?
How can you run GUI applications in a Docker container?
Are there any images that set up vncserver
or something so that you can - for example - add an extra speedbump sandbox around say Firefox?
With docker data volumes it's very easy to expose xorg's unix domain socket inside the container.
For example, with a Dockerfile like this:
You could do the following:
This of course is essentially the same as X-forwarding. It grants the container full access to the xserver on the host, so it's only recommended if you trust what's inside.
Note: If you are concerned about security, a better solution would be to confine the app with mandatory- or role-based-access control. Docker achieves pretty good isolation, but it was designed with a different purpose in mind. Use AppArmor, SELinux, or GrSecurity, which were designed to address your concern.
While the answer by Jürgen Weigert essentially covers this solution, it wasn't clear to me at first what was being described there. So I'll add my take on it, in case anyone else needs clarification.
First off, the relevant documentation is the X security manpage.
Numerous online sources suggest just mounting the X11 unix socket and the
~/.Xauthority
file into the container. These solutions often work by luck, without really understanding why, e.g. the container user ends up with the same UID as the user, so there's no need for magic key authorization.First off, the Xauthority file has mode 0600, so the container user won't be able to read it unless it has the same UID.
Even if you copy the file into the container, and change the ownership, there's still another problem. If you run
xauth list
on the host and container, with the sameXauthority
file, you'll see different entries listed. This is becausexauth
filters the entries depending on where it's run.The X client in the container (i.e. GUI app) will behave the same as
xauth
. In other words, it doesn't see the magic cookie for the X session running on the user's desktop. Instead, it sees the entries for all the "remote" X sessions you've opened previously (explained below).So, what you need to do is add a new entry with the hostname of the container and the same hex key as the host cookie (i.e. the X session running on your desktop), e.g.:
The catch is that the cookie has to be added with
xauth add
inside the container:Otherwise,
xauth
tags it in a way that it's only seen outside the container.The format for this command is:
Where
.
represents theMIT-MAGIC-COOKIE-1
protocol.Note: There's no need to copy or bind-mount
.Xauthority
into the container. Just create a blank file, as shown, and add the cookie.Jürgen Weigert's answer gets around this by using the
FamilyWild
connection type to create a new authority file on the host and copy it into the container. Note that it first extracts the hex key for the current X session from~/.Xauthority
usingxauth nlist
.So the essential steps are:
FamilyWild
connection type).I admit that I don't understand very well how
FamilyWild
works, or howxauth
or X clients filter entries from the Xauthority file depending where they're run. Additional information on this is welcome.If you want to distribute your Docker app, you'll need a start script for running the container that gets the hex key for the user's X session, and imports it into the container in one of the two ways explained previously.
It also helps to understand the mechanics of the authorization process:
$DISPLAY
./tmp/.X11-unix
directory mounted in the container.Note: The X11 Unix socket still needs to be mounted in the container, or the container will have no route to the X server. Most distributions disable TCP access to the X server by default for security reasons.
For additional information, and to better grasp how the X client/server relationship works, it's also helpful to look at the example case of SSH X forwarding:
$DISPLAY
in the SSH session to point to its own X server.xauth
to create a new cookie for the remote host, and adds it to theXauthority
files for both the local and remote users.Sharing host display :0, as stated in some other answers, has two drawbacks:
xev
orxinput
is possible, and remote control of host applications withxdotool
.--ipc=host
).Below an example script to run a docker image in Xephyr that addresses this issues.
--cap-drop ALL --security-opt no-new-privileges
. Also the container user is not root.The script expects some arguments, first a host window manager to run in Xephyr, second a docker image, optionally third an image command to be executed. To run a desktop environment in docker, use ":" instead of a host window manager.
Closing Xephyr window terminates docker container applications. Terminating the dockered applications closes Xephyr window.
Examples:
xephyrdocker "openbox --sm-disable" x11docker/lxde pcmanfm
xephyrdocker : x11docker/lxde
xephyrdocker xfwm4 --device /dev/snd jess/nes /games/zelda.rom
xephyrdocker script:
This script is maintained at x11docker wiki. A more advanced script is x11docker that also supports features like GPU acceleration, webcam and printer sharing and so on.
The solution given at http://fabiorehm.com/blog/2014/09/11/running-gui-apps-with-docker/ does seem to be an easy way of starting GUI applications from inside the containers ( I tried for firefox over ubuntu 14.04) but I found that a small additional change is required to the solution posted by the author.
Specifically, for running the container, the author has mentioned:
But I found that (based on a particular comment on the same site) that two additional options
and
need to be specified while running the container for firefox to work properly:
I have created a docker image with the information on that page and these additional findings: https://hub.docker.com/r/amanral/ubuntu-firefox/
I just found this blog entry and want to share it here with you because I think it is the best way to do it and it is so easy.
http://fabiorehm.com/blog/2014/09/11/running-gui-apps-with-docker/
PROS:
+ no x server stuff in the docker container
+ no vnc client/server needed
+ no ssh with x forwarding
+ much smaller docker containers
CONS:
- using x on the host (not meant for secure-sandboxing)
in case the link will fail someday I have put the most important part here:
dockerfile:
build the image:
and the run command:
of course you can also do this in the run command with
sh -c "echo script-here"
HINT: for audio take a look at: https://stackoverflow.com/a/28985715/2835523
This is not lightweight but is a nice solution that gives docker feature parity with full desktop virtualization. Both Xfce4 or IceWM for Ubuntu and CentOS work, and the
noVNC
option makes for an easy access through a browser.https://github.com/ConSol/docker-headless-vnc-container
It runs
noVNC
as well astigerVNC
's vncserver. Then it callsstartx
for given Window Manager. In addition,libnss_wrapper.so
is used to emulate password management for the users.