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

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


当前回答

我来晚了,但对于不想走XQuartz道路的Mac用户,这里有一个工作示例,它使用Xvfb和VNC使用桌面环境(xfce)构建Fedora映像。这很简单,也很有效:

https://github.com/ddual/docker_recipes#fedora-with-an-x-window-system https://github.com/ddual/docker_recipes/tree/master/fedora_gui

在Mac上,您可以使用屏幕共享(默认)应用程序访问它,连接到localhost:5901。

Dockerfile:

FROM fedora

USER root

# Set root password, so I know it for the future
RUN echo "root:password123" | chpasswd

# Install Java, Open SSL, etc.
RUN dnf update -y --setopt=deltarpm=false  \
 && dnf install -y --setopt=deltarpm=false \
                openssl.x86_64             \
                java-1.8.0-openjdk.x86_64  \
                xorg-x11-server-Xvfb       \
                x11vnc                     \
                firefox                    \
                @xfce-desktop-environment  \
 && dnf clean all

# Create developer user (password: password123, uid: 11111)
RUN useradd -u 11111 -g users -d /home/developer -s /bin/bash -p $(echo password123 | openssl passwd -1 -stdin) developer

# Copy startup script over to the developer home
COPY start-vnc.sh /home/developer/start-vnc.sh
RUN chmod 700 /home/developer/start-vnc.sh
RUN chown developer.users /home/developer/start-vnc.sh

# Expose VNC, SSH
EXPOSE 5901 22

# Set up VNC Password and DisplayEnvVar to point to Display1Screen0
USER developer
ENV  DISPLAY :1.0
RUN  mkdir ~/.x11vnc
RUN  x11vnc -storepasswd letmein ~/.x11vnc/passwd

WORKDIR /home/developer
CMD ["/home/developer/start-vnc.sh"]

start-vnc.sh

#!/bin/sh

Xvfb :1 -screen 0 1024x768x24 &
sleep 5
x11vnc -noxdamage -many -display :1 -rfbport 5901 -rfbauth ~/.x11vnc/passwd -bg
sleep 2
xfce4-session &

bash
# while true; do sleep 1000; done

如果需要,请查看链接的自述文件以获得构建和运行命令。

其他回答

这里有一个轻量级的解决方案,可以避免在容器上安装任何X服务器,vnc服务器或sshd守护进程。它在简单中得到的好处,却在安全和隔离中失去了。

它假设您使用带有X11转发的ssh连接到主机。

在主机的sshd配置中添加该行

X11UseLocalhost no

因此,主机上转发的X服务器端口在所有接口上都是开放的(不仅仅是lo),特别是在Docker虚拟接口docker0上。

容器在运行时需要访问. xauthority文件,以便连接到服务器。为此,我们定义了一个只读卷,指向主机上的主目录(可能不是一个明智的主意!),并相应地设置XAUTHORITY变量。

docker run -v $HOME:/hosthome:ro -e XAUTHORITY=/hosthome/.Xauthority

这还不够,我们还必须从主机传递DISPLAY变量,但是用ip代替主机名:

-e DISPLAY=$(echo $DISPLAY | sed "s/^.*:/$(hostname -i):/")

我们可以定义一个别名:

 alias dockerX11run='docker run -v $HOME:/hosthome:ro -e XAUTHORITY=/hosthome/.Xauthority -e DISPLAY=$(echo $DISPLAY | sed "s/^.*:/$(hostname -i):/")'

然后像这样测试:

dockerX11run centos xeyes

您也可以使用subuser: https://github.com/timthelion/subuser

这允许你在docker中打包许多gui应用程序。到目前为止,Firefox和emacs已经进行了测试。然而,在firefox中,webGL却不能正常工作。铬根本不起作用。

编辑:声音工作!

EDIT2:自从我第一次发布这篇文章以来,subbuser已经取得了很大的进步。我现在有了一个subuser.org网站,以及一个通过XPRA桥接连接到X11的新安全模型。

使用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,它们是为解决您的问题而设计的。

你可以允许Docker用户(这里是root)访问X11显示:

XSOCK=/tmp/.X11-unix
xhost +SI:localuser:root 
docker run -t -i --rm -v $XSOCK:$XSOCK:ro -e DISPLAY=unix$(DISPLAY) image 
xhost -SI:localuser:root

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/