如何在Linux Docker容器中运行GUI应用程序?

是否有任何图像设置vncserver或其他东西,以便您可以-例如-在Firefox周围添加额外的加速沙箱?


当前回答

使用docker数据卷,在容器中暴露xorg的unix域套接字是非常容易的。

例如,使用这样的Dockerfile:

FROM debian
RUN apt-get update
RUN apt-get install -qqy x11-apps
ENV DISPLAY :0
CMD xeyes

你可以这样做:

$ docker build -t xeyes - < Dockerfile
$ XSOCK=/tmp/.X11-unix/X0
$ docker run -v $XSOCK:$XSOCK xeyes

当然,这本质上与x转发是一样的。它授予容器对主机上的xserver的完全访问权,因此只有当您信任其中的内容时才建议使用它。

注意:如果你担心安全问题,更好的解决方案是使用强制性或基于角色的访问控制来限制应用程序。Docker实现了相当好的隔离,但它在设计时考虑到了不同的目的。使用AppArmor、SELinux或GrSecurity,它们是为解决您的问题而设计的。

其他回答

对于使用Nvidia驱动程序的OpenGL渲染,请使用以下图像:

https://github.com/thewtex/docker-opengl-nvidia

对于其他OpenGL实现,确保映像具有与主机相同的实现。

使用docker数据卷,在容器中暴露xorg的unix域套接字是非常容易的。

例如,使用这样的Dockerfile:

FROM debian
RUN apt-get update
RUN apt-get install -qqy x11-apps
ENV DISPLAY :0
CMD xeyes

你可以这样做:

$ docker build -t xeyes - < Dockerfile
$ XSOCK=/tmp/.X11-unix/X0
$ docker run -v $XSOCK:$XSOCK xeyes

当然,这本质上与x转发是一样的。它授予容器对主机上的xserver的完全访问权,因此只有当您信任其中的内容时才建议使用它。

注意:如果你担心安全问题,更好的解决方案是使用强制性或基于角色的访问控制来限制应用程序。Docker实现了相当好的隔离,但它在设计时考虑到了不同的目的。使用AppArmor、SELinux或GrSecurity,它们是为解决您的问题而设计的。

具有BRIDGE网络的Docker。 Ubuntu 16.04使用显示管理器lightdm:

cd /etc/lightdm/lightdm.conf.d
sudo nano user.conf

[Seat:*]
xserver-allow-tcp=true
xserver-command=X -listen tcp

您可以使用更多的私有权限

xhost +

docker run --volume="$HOME/.Xauthority:/root/.Xauthority:rw" --env="DISPLAY=$HOST_IP_IN_BRIDGE_NETWORK:0" --net=bridge $container_name

如果您已经构建了映像,还有另一个答案:

使用sudo调用docker (如何修复docker:获得许可被拒绝的问题) 在主机和容器共享之间共享相同的USER & home & passwd (提示:使用用户id代替用户名) 驱动相关库的dev文件夹工作得很好 加上X11向前。

    docker run --name=CONTAINER_NAME --network=host --privileged \
      -v /dev:/dev \
      -v `echo ~`:/home/${USER} \
      -p 8080:80 \
      --user=`id -u ${USER}` \
      --env="DISPLAY" \
      --volume="/etc/group:/etc/group:ro" \
      --volume="/etc/passwd:/etc/passwd:ro" \
      --volume="/etc/shadow:/etc/shadow:ro" \
      --volume="/etc/sudoers.d:/etc/sudoers.d:ro" \
      --volume="/tmp/.X11-unix:/tmp/.X11-unix:rw" \
      -it REPO:TAG /bin/bash

你可能会问,如果这么多东西都是一样的,那么使用docker还有什么意义呢?嗯,我能想到的一个原因是克服软件包依赖的地狱(https://en.wikipedia.org/wiki/Dependency_hell)。

所以我认为这种用法更适合开发人员。

http://fabiorehm.com/blog/2014/09/11/running-gui-apps-with-docker/上给出的解决方案似乎是在容器内启动GUI应用程序的一种简单方法(我尝试在ubuntu 14.04上使用firefox),但我发现需要对作者发布的解决方案进行一个小小的额外更改。

具体来说,对于运行容器,作者已经提到:

    docker run -ti --rm \
    -e DISPLAY=$DISPLAY \
    -v /tmp/.X11-unix:/tmp/.X11-unix \
    firefox

但我发现(根据同一网站上的一个特定评论)有两个额外的选项

    -v $HOME/.Xauthority:$HOME/.Xauthority

and

    -net=host 

需要在运行容器时指定,以便firefox正常工作:

    docker run -ti --rm \
    -e DISPLAY=$DISPLAY \
    -v /tmp/.X11-unix:/tmp/.X11-unix \
    -v $HOME/.Xauthority:$HOME/.Xauthority \
    -net=host \
    firefox

我已经创建了一个docker映像,其中包含该页面的信息和这些额外的发现:https://hub.docker.com/r/amanral/ubuntu-firefox/