如何在Linux Docker容器中运行GUI应用程序?
是否有任何镜像可以设置vncserver
或其他内容,以便您可以在例如Firefox周围添加额外的保护层?
这并不是轻量级的解决方案,但是它可以让docker与完整桌面虚拟化实现功能平衡。Ubuntu和CentOS都适用于Xfce4或IceWM。而noVNC
选项可以通过浏览器轻松访问。
https://github.com/ConSol/docker-headless-vnc-container
它运行noVNC
和tigerVNC
的vncserver。然后调用给定的窗口管理器的startx
。此外,libnss_wrapper.so
用于模拟用户的密码管理。
xpra
,它是无需root的X。在我看来,xpra
最合适,比VNC更高效。 - dashesy--device /dev/...
传递给docker并设置必要的--cap
权限。这违背了容器化的目的,但您可以通过设备进行传递。通过一些调整,我相信在VNC下运行GNOME/KDE是可能的。我在带有nvidia卡的docker中运行了多个X(没有VNC或Xpra),所以这肯定是可行的。 - dashesydocker-compose
的解决方案。docker-compose.yml
文件中:version: '2'
services:
node:
build: .
container_name: node
environment:
- DISPLAY
volumes:
- /tmp/.X11-unix:/tmp/.X11-unix
在终端或脚本中:
xhost +si:localuser:$USER
(允许当前用户访问X服务器)xhost +local:docker
(允许Docker容器访问X服务器)export DISPLAY=$DISPLAY
(设置显示环境变量为当前X服务器)docker-compose up
(启动Docker Compose服务)xvfb
或其他类似软件创建虚拟监视器。例如,如果您想在浏览器中运行Selenium测试,这非常有帮助。--privileged
。虽然我来晚了,但是对于不想使用XQuartz的Mac用户,这里提供一个可以构建Fedora Image且带有桌面环境(xfce)的工作示例,它使用了Xvfb
和VNC
,非常简单易用:
在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
如果您需要,可以查看链接的自述文件获取构建和运行命令。
根据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 目录挂载到 docker 容器中,而非挂载 $XAUTH 文件。
这种方法的好处是,您可以在 /etc/rc.local 中编写一个命令,在 /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目录。在用户登录后,您可以在~/.profile中编写一个命令来创建$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文件。
我按照以下步骤成功地在 docker
中使用 opencv
运行 USB 摄像头的视频流:
Let docker access the X server
xhost +local:docker
Create the X11 Unix socket and the X authentication file
XSOCK=/tmp/.X11-unix
XAUTH=/tmp/.docker.xauth
Add proper permissions
xauth nlist $DISPLAY | sed -e 's/^..../ffff/' | xauth -f $XAUTH nmerge -
Set the Qt rendering speed to "native", so it doesn't bypass the X11 rendering engine
export QT_GRAPHICSSYSTEM=native
Tell Qt to not use MIT-SHM (shared memory) - that way it should be also safer security-wise
export QT_X11_NO_MITSHM=1
Update the docker run command
docker run -it \
-e DISPLAY=$DISPLAY \
-e XAUTHORITY=$XAUTH \
-v $XSOCK:$XSOCK \
-v $XAUTH:$XAUTH \
--runtime=nvidia \
--device=/dev/video0:/dev/video0 \
nvcr.io/nvidia/pytorch:19.10-py3
注意:完成项目后,请将访问控制返回到默认值 - xhost -local:docker
更多细节请参见:使用Docker的GUI
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
在不使用sudo的情况下调用docker(如何解决docker:权限被拒绝问题)
在主机和容器之间共享相同的用户、主目录和密码(提示:使用用户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
echo ~
:/home/${USER} --user=id -u ${USER}
--env="DISPLAY" --volume="/etc/passwd:/etc/passwd:ro" -it REPO:TAG /bin/bash - user1145922