By default, a Docker container won't be able to run a GUI application.
Before that, the X11 socket must be forwarded first to the container, so it can be used directly. The DISPLAY environment variable must be forwarded as well:
docker run -v /tmp/.X11-unix:/tmp/.X11-unix -e DISPLAY=unix$DISPLAY <image-name>
This will fail at first, since we didn't set the permissions to the X server host:
cannot connect to X server unix:0
The quickest (but not safest) way is to allow access directly with:
xhost +local:root
After finishing with the container, we can go back to the original state with:
xhost -local:root
Another (safer) way is to prepare a Dockerfile that will build a new image that will use the our user credentials to access the X server:
FROM <iamge-name>
MAINTAINER <you>
# Arguments picked from the command line!
ARG user
ARG uid
ARG gid
#Add new user with our credentials
ENV USERNAME ${user}
RUN useradd -m $USERNAME && \
echo "$USERNAME:$USERNAME" | chpasswd && \
usermod --shell /bin/bash $USERNAME && \
usermod --uid ${uid} $USERNAME && \
groupmod --gid ${gid} $USERNAME
USER ${user}
WORKDIR /home/${user}
When invoking docker build
from the command line, we have to pass the ARG variables that appear in the Dockerfile:
docker build --build-arg user=$USER --build-arg uid=$(id -u) --build-arg gid=$(id -g) -t <new-image-with-X11-enabled-name> -f <Dockerfile-for-X11> .
Now, before spawning a new container, we have to create a xauth file with access permission:
xauth nlist $DISPLAY | sed -e 's/^..../ffff/' | xauth -f /tmp/.docker.xauth nmerge -
This file has to be mounted into the container when creating/running it:
docker run -e DISPLAY=unix$DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix -v /tmp/.docker.xauth:/tmp/.docker.xauth:rw -e XAUTHORITY=/tmp/.docker.xauth