在 Linux 容器中运行 GUI 应用程序
默认情况下,Docker 容器将无法运行 GUI 应用程序。
在此之前,X11 套接字必须首先转发到容器,因此可以直接使用。还必须转发 DISPLAY 环境变量:
docker run -v /tmp/.X11-unix:/tmp/.X11-unix -e DISPLAY=unix$DISPLAY <image-name>
这将首先失败,因为我们没有设置 X 服务器主机的权限:
cannot connect to X server unix:0
最快(但不是最安全)的方法是允许直接访问:
xhost +local:root
完成容器后,我们可以回到原始状态:
xhost -local:root
另一种(更安全)的方法是准备一个 Dockerfile,它将构建一个新的映像,它将使用我们的用户凭据来访问 X 服务器:
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}
从命令行调用 docker build
时,我们必须传递 Dockerfile 中出现的 ARG 变量:
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> .
现在,在生成一个新容器之前,我们必须创建一个具有访问权限的 xauth 文件:
xauth nlist $DISPLAY | sed -e 's/^..../ffff/' | xauth -f /tmp/.docker.xauth nmerge -
创建/运行此文件时,必须将其挂载到容器中:
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