# 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'
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"]
1. in one mac terminal i started:
socat TCP-LISTEN:6000,reuseaddr,fork UNIX-CLIENT:\"$DISPLAY\"
2. and in another mac terminal I ran:
docker run -ti --rm \
-e DISPLAY=$(ipconfig getifaddr en0):0 \
-v /tmp/.X11-unix:/tmp/.X11-unix \
firefox
我也能从我的debian docker容器中启动CLion .
8
Docker与BRIDGE网络 . 对于带有显示管理器lightdm的Ubuntu 16.04:
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
20 回答
有another solution by lord.garbage在容器中运行GUI应用程序而不使用VNC,SSH和X11转发 . 它也被提及here .
如果要运行GUI应用程序无头,请阅读here . 您需要做的是使用
xvfb
或其他类似软件创建虚拟监视器 . 如果您想要使用浏览器运行Selenium测试,这非常有用 .在任何地方都没有提到的是,有些软件实际上自己使用沙盒与Linux容器 . 因此,例如,如果在运行容器时未使用相应的标志
--privileged
,则Chrome将永远无法正常运行 .你可以简单地安装一个vncserver和Firefox :)
我推了一个图片,vnc / firefox,这里:
docker pull creack/firefox-vnc
该镜像是使用此Dockerfile制作的:
这将创建一个运行VNC的Docker容器,密码为
1234
:对于Docker 1.3或更高版本:
对于版本1.3之前的Docker:
Xauthority成为新系统的问题 . 在运行我的docker容器之前,我可以使用xhost丢弃任何保护,或者我可以传入一个准备充分的Xauthority文件 . 典型的Xauthority文件是特定于主机名的 . 使用docker,每个容器可以有不同的主机名(使用docker run -h设置),但即使将容器的主机名设置为与主机系统相同也无济于事 . xeyes(我喜欢这个例子)只是忽略魔术cookie并且不向服务器传递凭证 . 因此,我们收到错误消息“未指定协议无法打开显示”
可以以某种方式编写Xauthority文件,以便主机名无关紧要 . 我们需要将Authentication Family设置为'FamilyWild' . 我不确定,如果xauth有一个适当的命令行,所以这里有一个结合xauth和sed来做到这一点的例子 . 我们需要更改nlist输出的前16位 . FamilyWild的值为65535或0xffff .
我刚刚找到了这篇博客文章,想在这里与大家分享,因为我觉得这是最好的方式,而且很容易 .
http://fabiorehm.com/blog/2014/09/11/running-gui-apps-with-docker/
优点:
在docker容器中没有x服务器的东西
不需要vnc客户端/服务器
没有ssh与x转发
更小的码头集装箱
缺点:
如果有一天链接失败,我把最重要的部分放在这里:
dockerfile:
Build 图像:
和运行命令:
当然你也可以在运行命令中使用
sh -c "echo script-here"
执行此操作提示:对于音频,请看:https://stackoverflow.com/a/28985715/2835523
使用docker数据卷,可以很容易地在容器中公开xorg的unix域套接字 .
例如,使用这样的Dockerfile:
您可以执行以下操作:
这当然与X-forwarding基本相同 . 它授予容器对主机上xserver的完全访问权限,因此只有在您信任其中的内容时才建议使用它 .
Note: 如果您担心安全性,更好的解决方案是将应用程序限制为mandatory-或role-based-访问控制 . Docker实现了相当好的隔离,但它的设计考虑了不同的目的 . 使用AppArmor,SELinux或GrSecurity,旨在解决您的问题 .
您也可以使用子用户:https://github.com/timthelion/subuser
这允许您在docker中打包许多gui应用程序 . 到目前为止,Firefox和emacs已经过测试 . 使用firefox,webGL不起作用 . 铬根本不起作用 .
编辑:声音工作!
编辑2:自从我第一次发布这篇文章以来,子用户已经取得了很大的进步 . 我现在有一个subuser.org的网站,以及一个用于连接到X11 via XPRA bridging的新安全模型 .
OSX
Jürgen Weigert具有在Ubuntu上为我工作的最佳答案,但是在OSX上,docker在VirtualBox内部运行,因此如果没有更多的工作,解决方案将无法工作 .
我已经使用这些额外的成分:
Xquartz(OSX不再附带X11服务器)
使用socat进行
套接字转发(brew install socat)
bash脚本启动容器
我很感激用户评论来改进OSX的答案,我不确定X的套接字转发是否安全,但我的目的是仅在本地运行docker容器 .
此外,该脚本有点脆弱,因为它不是很容易获得机器的IP地址,因为它在我们的本地无线上,因此它总是一些随机IP .
我用来启动容器的BASH脚本:
我能够让xeyes和matplotlib使用这种方法 .
Windows 7
使用MobaXterm在Windows 7上更容易一些:
为Windows安装MobaXterm
启动MobaXterm
配置X服务器: Settings - > X11 (tab) - >设置 X11 Remote Access 至 full
使用此BASH脚本启动容器
run_docker.bash
:这是一个轻量级的解决方案,可以避免在容器上安装任何
X
服务器,vnc
服务器或sshd
守护程序 . 它在简单性方面取得的成就在安全性和隔离性方面失败了 .它假定您使用带有
X11
转发的ssh
连接到主机 .在主机的
sshd
配置中,添加该行这样主机上转发的X服务器端口就会在所有接口上打开(不仅仅是
lo
),特别是在Docker虚拟接口docker0
上 .容器在运行时需要访问
.Xauthority
文件,以便它可以连接到服务器 . 为了做到这一点,我们定义了一个指向主机上主目录的只读卷(可能不是一个明智的想法!),并相应地设置XAUTHORITY
变量 .这还不够,我们还必须从主机传递DISPLAY变量,但用ip替换主机名:
我们可以定义一个别名:
并像这样测试:
共享主机显示:0,如其他一些答案中所述,有两个缺点:
由于某些X安全漏洞,它打破了容器隔离 . 例如,可以使用
xev
或xinput
进行键盘记录,并使用xdotool
远程控制主机应用程序 .由于缺少X扩展MIT-SHM的共享内存,应用程序可能会出现渲染故障和RAM访问错误 . (也可以使用隔离降级选项
--ipc=host
进行修复) .下面是一个示例脚本,用于在Xephyr中运行一个解决此问题的docker镜像 .
它避免了X安全漏洞,因为docker应用程序在嵌套的X服务器中运行 .
禁用MIT-SHM以避免RAM访问失败 .
使用
--cap-drop ALL --security-opt no-new-privileges
改进了容器安全性 . 容器用户也不是root用户 .创建X cookie以限制对Xephyr显示的访问 .
该脚本需要一些参数,首先是在Xephyr中运行的主机窗口管理器,第二个是docker镜像,可选地是第三个要执行的image命令 . 要在docker中运行桌面环境,请使用“:”而不是主机窗口管理器 .
关闭Xephyr窗口会终止docker容器应用程序 . 终止停靠应用程序将关闭Xephyr窗口 .
Examples:
xephyrdocker "openbox --sm-disable" x11docker/lxde pcmanfm
xephyrdocker : x11docker/lxde
xephyrdocker xfwm4 --device /dev/snd jess/nes /games/zelda.rom
xephyrdocker script:
此脚本维护在x11docker wiki . 更高级的脚本是x11docker,它还支持GPU加速,网络摄像头和打印机共享等功能 .
这不是轻量级的,但它是一个很好的解决方案,使docker功能与完整的桌面虚拟化相同 . 用于Ubuntu和CentOS的Xfce4或IceWM都可以工作,而
noVNC
选项可以通过浏览器轻松访问 .https://github.com/ConSol/docker-headless-vnc-container
它运行
noVNC
以及tigerVNC
的vncserver . 然后它为给定的窗口管理器调用startx
. 此外,libnss_wrapper.so
用于模拟用户的密码管理 .在http://fabiorehm.com/blog/2014/09/11/running-gui-apps-with-docker/给出的解决方案似乎确实是一种从容器内部启动GUI应用程序的简单方法(我在ubuntu 14.04上尝试使用firefox)但我发现作者发布的解决方案需要进行一些额外的更改 .
具体来说,为了运行容器,作者提到:
但我发现(基于对同一网站的特定评论)有两个额外的选项
和
需要在运行容器时指定firefox才能正常工作:
我创建了一个docker镜像,其中包含该页面上的信息以及这些额外的发现:https://hub.docker.com/r/amanral/ubuntu-firefox/
根据Jürgen Weigert的回答,我有一些改进:
唯一的区别是它创建了一个目录$ XAUTH_DIR,用于放置$ XAUTH文件并挂载$ XAUTH_DIR目录而不是$ XAUTH文件到docker容器中 .
这种方法的好处是你可以在/etc/rc.local中编写一个命令,即在/ tmp中创建一个名为$ XAUTH_DIR的空文件夹,并将其模式更改为777 .
系统重启时,在用户登录之前,如果容器的重启策略为“always”,则docker将自动挂载$ XAUTH_DIR目录 . 用户登录后,您可以在〜/ .profile中编写一个命令来创建$ XAUTH文件,然后容器将自动使用这个$ XAUTH文件 .
毕竟,每次系统重启和用户登录时,容器都会自动获取Xauthority文件 .
尽管Jürgen Weigert的回答基本上涵盖了这个解决方案,但是如果其他人需要澄清的话,那就不会加以我的看法 .
首先,相关文档是X security manpage .
许多在线消息来源建议只需将X11 unix套接字和
~/.Xauthority
文件安装到容器中即可 . 这些解决方案通常可以运气,但不能真正理解为什么,例如容器用户最终使用与用户相同的UID,因此不需要魔术密钥授权 .首先,Xauthority文件具有模式0600,因此容器用户将无法读取它,除非它具有相同的UID .
即使您将文件复制到容器中并更改所有权,仍然存在另一个问题 . 如果在主机和容器上运行
xauth list
,并使用相同的Xauthority
文件,则会看到列出的不同条目 . 这是因为xauth
根据条目的运行位置过滤条目 .容器中的X客户端(即GUI应用程序)的行为与
xauth
相同 . 换句话说,它不是桌面 . 相反,它会看到您之前打开的所有"remote" X会话的条目(如下所述) .因此,您需要做的是添加一个新条目,其中包含容器的主机名和与主机cookie相同的十六进制密钥(即在桌面上运行的X会话),例如:
问题是必须在容器内添加
xauth add
的cookie:否则,
xauth
标记它只能在容器外看到它 .该命令的格式为:
.
表示MIT-MAGIC-COOKIE-1
协议 .Note: 无需将
.Xauthority
复制或绑定到容器中 . 只需创建一个空白文件,如图所示,然后添加cookie .Jürgen Weigert的答案通过使用
FamilyWild
连接类型在主机上创建新的授权文件并将其复制到容器中来解决这个问题 . 请注意,它首先使用xauth nlist
从~/.Xauthority
中提取当前X会话的十六进制密钥 .所以必要的步骤是:
为用户当前的X会话提取cookie的十六进制密钥 .
使用容器主机名和共享十六进制密钥在容器中创建一个新的Xauthority文件(或创建一个具有
FamilyWild
连接类型的cookie) .我承认我不太了解
FamilyWild
如何工作,或者xauth
或X客户端如何从Xauthority文件中过滤条目,具体取决于它们的运行位置 . 欢迎提供更多相关信息 .如果要分发Docker应用程序,则需要一个启动脚本来运行容器,该容器获取用户X会话的十六进制密钥,并以前面解释的两种方式之一将其导入容器 .
它还有助于理解授权过程的机制:
在容器中运行的X客户端(即GUI应用程序)在Xauthority文件中查找与容器的主机名和
$DISPLAY
的值匹配的cookie条目 .如果找到匹配的条目,X客户端将通过其授权请求将其传递给X服务器,通过容器中安装的
/tmp/.X11-unix
目录中的相应套接字 .Note: X11 Unix套接字仍然需要安装在容器中,否则容器将没有到X服务器的路由 . 出于安全原因,大多数发行版默认禁用对X服务器的TCP访问 .
有关其他信息,为了更好地掌握X客户端/服务器关系的工作原理,查看SSH X转发的示例案例也很有帮助:
在远程计算机上运行的SSH服务器模拟自己的X服务器 .
它将SSH会话中
$DISPLAY
的值设置为指向其自己的X服务器 .它使用
xauth
为远程主机创建一个新cookie,并将其添加到Xauthority
文件中本地和远程用户 .启动GUI应用程序时,它们会与SSH的模拟X服务器通信 .
SSH服务器将此数据转发回本地桌面上的SSH客户端 .
本地SSH客户端将数据发送到桌面上运行的X服务器会话,就像SSH客户端实际上是X客户端(即GUI应用程序)一样 .
X服务器使用接收的数据在桌面上呈现GUI .
在此交换开始时,远程X客户端还使用刚刚创建的cookie发送授权请求 . 本地X服务器将其与本地副本进行比较 .
对于使用Nvidia驱动程序的OpenGL渲染,请使用以下图像:
https://github.com/thewtex/docker-opengl-nvidia
对于其他OpenGL实现,请确保该映像具有与主机相同的实现 .
我想要沿着XQuartz路径走下去,这是一个使用
Xvfb
和VNC
构建Fedora映像的桌面环境(xfce)的工作示例 . 它很简单,有效:https://github.com/ddual/docker_recipes#fedora-with-an-x-window-system
https://github.com/ddual/docker_recipes/tree/master/fedora_gui
在Mac上,您只需使用 Screen Sharing (默认)应用程序访问它,连接到
localhost:5901
.Dockerfile:
start-vnc.sh
如果需要/需要,请检查链接的readme以获取构建和运行命令 .
您可以允许Docker用户(此处为:root)访问X11显示:
其他解决方案应该有效,但这是
docker-compose
的解决方案 .要修复该错误,您需要将$ DISPLAY和.X11-unix传递给docker,并向启动了docker访问xhost的用户授予权限 .
在docker-compose.yml中:
version: '2' services: node: build: . container_name: node environment: - DISPLAY volumes: - /tmp/.X11-unix:/tmp/.X11-unix
在终端或脚本中:
xhost +si:localuser:$USER
xhost +local:docker
export DISPLAY=$DISPLAY
docker-compose up
OSX(10.13.6,高山脉)
与@Nick的答案类似,但他的解决方案对我不起作用 .
首先通过
brew install socat
安装socat,然后安装XQuartz(https://www.xquartz.org/)然后在评论部分中按照以下步骤(http://fabiorehm.com/blog/2014/09/11/running-gui-apps-with-docker/)进行操作:
我也能从我的debian docker容器中启动CLion .
Docker与BRIDGE网络 . 对于带有显示管理器lightdm的Ubuntu 16.04:
您可以使用更多私人权限