如何在Linux Docker容器中运行GUI应用程序?
是否有任何图像设置vncserver或其他东西,以便您可以-例如-在Firefox周围添加额外的加速沙箱?
如何在Linux Docker容器中运行GUI应用程序?
是否有任何图像设置vncserver或其他东西,以便您可以-例如-在Firefox周围添加额外的加速沙箱?
当前回答
对于使用Nvidia驱动程序的OpenGL渲染,请使用以下图像:
https://github.com/thewtex/docker-opengl-nvidia
对于其他OpenGL实现,确保映像具有与主机相同的实现。
其他回答
你可以简单地安装一个vncserver和Firefox:)
我推了一个图像,vnc/firefox,在这里:docker拉creack/firefox-vnc
图片是用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'
这将创建一个运行VNC的Docker容器,密码为1234:
对于Docker 18或更新版本:
docker run -p 5900:5900 -e HOME=/ creack/firefox-vnc x11vnc -forever -usepw -create
对于Docker 1.3或更新版本:
docker run -p 5900 -e HOME=/ creack/firefox-vnc x11vnc -forever -usepw -create
对于1.3版本之前的Docker:
docker run -p 5900 creack/firefox-vnc x11vnc -forever -usepw -create
你可以允许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
根据Jürgen Weigert的回答,我有一些改进:
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_DIR=/tmp/.docker.xauth
XAUTH=$XAUTH_DIR/.xauth
mkdir -p $XAUTH_DIR && touch $XAUTH
xauth nlist $DISPLAY | sed -e 's/^..../ffff/' | xauth -f $XAUTH nmerge -
docker run -ti -v $XSOCK:$XSOCK -v $XAUTH_DIR:$XAUTH_DIR -e XAUTHORITY=$XAUTH xeyes
唯一的区别是它创建了一个目录$XAUTH_DIR,用于放置$XAUTH文件,并将$XAUTH_DIR目录而不是$XAUTH文件挂载到docker容器中。
这种方法的好处是你可以在/etc/rc.中写入命令在/tmp目录下创建一个名为$XAUTH_DIR的空文件夹,并将其模式更改为777。
tr '\n' '\000' < /etc/rc.local | sudo tee /etc/rc.local >/dev/null
sudo sed -i 's|\x00XAUTH_DIR=.*\x00\x00|\x00|' /etc/rc.local >/dev/null
tr '\000' '\n' < /etc/rc.local | sudo tee /etc/rc.local >/dev/null
sudo sed -i 's|^exit 0.*$|XAUTH_DIR=/tmp/.docker.xauth; rm -rf $XAUTH_DIR; install -m 777 -d $XAUTH_DIR\n\nexit 0|' /etc/rc.local
当系统重启时,在用户登录前,如果容器的重启策略为always, docker会自动挂载$XAUTH_DIR目录。用户登录后,可以在~/中写入命令。配置文件是创建$XAUTH文件,然后容器将自动使用这个$XAUTH文件。
tr '\n' '\000' < ~/.profile | sudo tee ~/.profile >/dev/null
sed -i 's|\x00XAUTH_DIR=.*-\x00|\x00|' ~/.profile
tr '\000' '\n' < ~/.profile | sudo tee ~/.profile >/dev/null
echo "XAUTH_DIR=/tmp/.docker.xauth; XAUTH=\$XAUTH_DIR/.xauth; touch \$XAUTH; xauth nlist \$DISPLAY | sed -e 's/^..../ffff/' | xauth -f \$XAUTH nmerge -" >> ~/.profile
毕竟,容器将在每次系统重新启动和用户登录时自动获取Xauthority文件。
我刚刚发现了这篇博客,想在这里与你们分享,因为我认为这是最好的方法,而且很简单。
http://fabiorehm.com/blog/2014/09/11/running-gui-apps-with-docker/
优点: + docker容器中没有x服务器的东西 +不需要VNC客户端/服务器 + SSH不支持x转发 +更小的docker容器
缺点: 在主机上使用x(不是为了安全沙箱)
以防链接有一天会失败,我把最重要的部分放在这里: dockerfile:
FROM ubuntu:14.04
RUN apt-get update && apt-get install -y firefox
# Replace 1000 with your user / group id
RUN export uid=1000 gid=1000 && \
mkdir -p /home/developer && \
echo "developer:x:${uid}:${gid}:Developer,,,:/home/developer:/bin/bash" >> /etc/passwd && \
echo "developer:x:${uid}:" >> /etc/group && \
echo "developer ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/developer && \
chmod 0440 /etc/sudoers.d/developer && \
chown ${uid}:${gid} -R /home/developer
USER developer
ENV HOME /home/developer
CMD /usr/bin/firefox
构建映像:
docker build -t firefox .
run命令:
docker run -ti --rm \
-e DISPLAY=$DISPLAY \
-v /tmp/.X11-unix:/tmp/.X11-unix \
firefox
当然,你也可以在运行命令中使用sh -c "echo script-here"
提示:音频请查看:https://stackoverflow.com/a/28985715/2835523
OSX
Jürgen Weigert有最好的答案,在Ubuntu上为我工作,然而在OSX上,docker运行在VirtualBox内部,所以解决方案没有更多的工作就不能工作。
我让它和这些额外的配料一起工作:
Xquartz (OSX不再随X11服务器发货) 使用socat进行Socket转发 Bash脚本启动容器
我很感激用户的评论来改善OSX的这个答案,我不确定套接字转发X是否安全,但我的预期用途是只在本地运行docker容器。
此外,该脚本有点脆弱,因为它不容易获得机器的IP地址,因为它是在我们的本地无线,所以它总是一些随机的IP。
我用来启动容器的BASH脚本:
#!/usr/bin/env bash
CONTAINER=py3:2016-03-23-rc3
COMMAND=/bin/bash
NIC=en0
# Grab the ip address of this box
IPADDR=$(ifconfig $NIC | grep "inet " | awk '{print $2}')
DISP_NUM=$(jot -r 1 100 200) # random display number between 100 and 200
PORT_NUM=$((6000 + DISP_NUM)) # so multiple instances of the container won't interfer with eachother
socat TCP-LISTEN:${PORT_NUM},reuseaddr,fork UNIX-CLIENT:\"$DISPLAY\" 2>&1 > /dev/null &
XSOCK=/tmp/.X11-unix
XAUTH=/tmp/.docker.xauth.$USER.$$
touch $XAUTH
xauth nlist $DISPLAY | sed -e 's/^..../ffff/' | xauth -f $XAUTH nmerge -
docker run \
-it \
--rm \
--user=$USER \
--workdir="/Users/$USER" \
-v "/Users/$USER:/home/$USER:rw" \
-v $XSOCK:$XSOCK:rw \
-v $XAUTH:$XAUTH:rw \
-e DISPLAY=$IPADDR:$DISP_NUM \
-e XAUTHORITY=$XAUTH \
$CONTAINER \
$COMMAND
rm -f $XAUTH
kill %1 # kill the socat job launched above
我能够让xeyes和matplotlib使用这种方法工作。
Windows 7 +。
在Windows 7+上使用MobaXterm更容易一些:
为windows安装MobaXterm 开始MobaXterm 配置X服务器:“设置”—“> X11 (tab)”—“> X11远程访问”设置为“full” 使用这个BASH脚本启动容器
run_docker.bash:
#!/usr/bin/env bash
CONTAINER=py3:2016-03-23-rc3
COMMAND=/bin/bash
DISPLAY="$(hostname):0"
USER=$(whoami)
docker run \
-it \
--rm \
--user=$USER \
--workdir="/home/$USER" \
-v "/c/Users/$USER:/home/$USER:rw" \
-e DISPLAY \
$CONTAINER \
$COMMAND