您可以在Docker容器中运行GUI应用程序吗?

本文翻译自:Can you run GUI applications in a Docker container?

How can you run GUI applications in a Docker container? 如何在Docker容器中运行GUI应用程序?

Are there any images that set up vncserver or something so that you can - for example - add an extra speedbump sandbox around say Firefox? 是否有设置vncserver图像或其他东西,例如,您可以在Firefox周围添加一个额外的speedbump沙箱?


#1楼

参考:https://stackoom.com/question/16NWr/您可以在Docker容器中运行GUI应用程序吗


#2楼

You can simply install a vncserver along with Firefox :) 您可以简单地与Firefox一起安装vncserver :)

I pushed an image, vnc/firefox, here: docker pull creack/firefox-vnc 我在这里推送了一个图像vnc / firefox: docker pull creack/firefox-vnc

The image has been made with this Dockerfile: 该镜像已使用以下Dockerfile生成:

# Firefox over VNC
#
# VERSION               0.1
# DOCKER-VERSION        0.2

FROM    ubuntu:12.04
# Make sure the package repository is up to date
RUN     echo "deb http://archive.ubuntu.com/ubuntu precise main universe" > /etc/apt/sources.list
RUN     apt-get update

# Install vnc, xvfb in order to create a 'fake' display and firefox
RUN     apt-get install -y x11vnc xvfb firefox
RUN     mkdir ~/.vnc
# Setup a password
RUN     x11vnc -storepasswd 1234 ~/.vnc/passwd
# Autostart firefox (might not be the best way to do it, but it does the trick)
RUN     bash -c 'echo "firefox" >> /.bashrc'

This will create a Docker container running VNC with the password 1234 : 这将创建一个运行VNC且密码为1234的Docker容器:

For Docker version 18 or newer: 对于Docker 18或更高版本:

docker run -p 5900:5900 -e HOME=/ creack/firefox-vnc x11vnc -forever -usepw -create

For Docker version 1.3 or newer: 对于Docker 1.3或更高版本:

docker run -p 5900 -e HOME=/ creack/firefox-vnc x11vnc -forever -usepw -create

For Docker before version 1.3: 对于1.3版之前的Docker:

docker run -p 5900 creack/firefox-vnc x11vnc -forever -usepw -create

#3楼

You can also use subuser: https://github.com/timthelion/subuser 您还可以使用子用户: https : //github.com/timthelion/subuser

This allows you to package many gui apps in docker. 这使您可以将许多gui应用程序打包在docker中。 Firefox and emacs have been tested so far. 到目前为止,Firefox和emacs已经过测试。 With firefox, webGL doesn't work though. 使用firefox,webGL不能正常工作。 Chromium doesn't work at all. 铬根本不起作用。

EDIT: Sound works! 编辑:声音有效!

EDIT2: In the time since I first posted this, subuser has progressed greatly. EDIT2:自从我第一次发布此内容以来,子用户有了很大的进步。 I now have a website up subuser.org , and a new security model for connecting to X11 via XPRA bridging . 我现在在subuser.org上拥有一个网站,以及一个用于通过XPRA桥接连接到X11的新安全模型。


#4楼

Here's a lightweight solution that avoids having to install any X server, vnc server or sshd daemon on the container. 这是一个轻量级的解决方案,可以避免在容器上安装任何X服务器, vnc服务器或sshd守护程序。 What it gains in simplicity it loses in security and isolation. 它在简单性方面获得的好处在安全性和隔离性方面失去了。

It assumes that you connect to the host machine using ssh with X11 forwarding. 假定您使用带有X11转发功能的ssh连接到主机。

In the sshd configuration of the host, add the line 在主机的sshd配置中,添加以下行

X11UseLocalhost no

So that the forwarded X server port on the host is opened on all interfaces (not just lo ) and in particular on the Docker virtual interface, docker0 . 以便主机上转发的X服务器端口在所有接口(不仅是lo )上都打开,尤其是在Docker虚拟接口docker0

The container, when run, needs access to the .Xauthority file so that it can connect to the server. 容器在运行时需要访问.Xauthority文件,以便它可以连接到服务器。 In order to do that, we define a read-only volume pointing to the home directory on the host (maybe not a wise idea!) and also set the XAUTHORITY variable accordingly. 为了做到这一点,我们定义了一个指向主机上主目录的只读卷(可能不是一个明智的主意!),并相应地设置了XAUTHORITY变量。

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

That is not enough, we also have to pass the DISPLAY variable from the host, but substituting the hostname by the ip: 这还不够,我们还必须从主机传递DISPLAY变量,但用ip替换主机名:

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

We can define an alias: 我们可以定义一个别名:

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

And test it like this: 并像这样测试它:

dockerX11run centos xeyes

#5楼

With docker data volumes it's very easy to expose xorg's unix domain socket inside the container. 使用docker数据卷,很容易将xorg的unix域套接字公开到容器内。

For example, with a Dockerfile like this: 例如,使用这样的Dockerfile:

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

You could do the following: 您可以执行以下操作:

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

This of course is essentially the same as X-forwarding. 当然,这本质上与X转发相同。 It grants the container full access to the xserver on the host, so it's only recommended if you trust what's inside. 它授予容器对主机上xserver的完全访问权限,因此仅在您信任其中的内容时才建议使用。

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. Docker实现了很好的隔离,但是在设计时考虑了不同的目的。 Use AppArmor , SELinux , or GrSecurity , which were designed to address your concern. 使用AppArmorSELinuxGrSecurity旨在解决您的问题。


#6楼

Xauthority becomes an issue with newer systems. Xauthority成为新系统的问题。 I can either discard any protection with xhost + before running my docker containers, or I can pass in a well prepared Xauthority file. 我可以在运行Docker容器之前放弃使用xhost +进行的任何保护,也可以传入准备充分的Xauthority文件。 Typical Xauthority files are hostname specific. 典型的Xauthority文件是特定于主机名的。 With docker, each container can have a different host name (set with docker run -h), but even setting the hostname of the container identical to the host system did not help in my case. 使用docker,每个容器可以具有不同的主机名(使用docker run -h设置),但是即使将容器的主机名设置为与主机系统相同也不能解决我的问题。 xeyes (I like this example) simply would ignore the magic cookie and pass no credentials to the server. xeyes(我喜欢这个示例)只会忽略魔术cookie,并且不会将凭据传递给服务器。 Hence we get an error message 'No protocol specified Cannot open display' 因此,我们收到一条错误消息“未指定协议,无法打开显示”

The Xauthority file can be written in a way so that the hostname does not matter. Xauthority文件的编写方式可以使主机名无关紧要。 We need to set the Authentication Family to 'FamilyWild'. 我们需要将身份验证系列设置为“ FamilyWild”。 I am not sure, if xauth has a proper command line for this, so here is an example that combines xauth and sed to do that. 我不确定xauth是否为此使用了正确的命令行,因此这是结合xauth和sed来执行此操作的示例。 We need to change the first 16 bits of the nlist output. 我们需要更改nlist输出的前16位。 The value of FamilyWild is 65535 or 0xffff. FamilyWild的值为65535或0xffff。

docker build -t xeyes - << __EOF__
FROM debian
RUN apt-get update
RUN apt-get install -qqy x11-apps
ENV DISPLAY :0
CMD xeyes
__EOF__
XSOCK=/tmp/.X11-unix
XAUTH=/tmp/.docker.xauth
xauth nlist :0 | sed -e 's/^..../ffff/' | xauth -f $XAUTH nmerge -
docker run -ti -v $XSOCK:$XSOCK -v $XAUTH:$XAUTH -e XAUTHORITY=$XAUTH xeyes
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值