运行 Chromium inside Docker - Gtk:无法打开显示::0

Running Chromium inside Docker - Gtk: cannot open display: :0

当我尝试在 docker 容器中 运行 铬时,我看到以下错误:Gtk:无法打开显示::0

Dockerfile:(基于https://registry.hub.docker.com/u/jess/chromium/dockerfile

FROM debian:jessie

# Install Chromium
RUN sed -i.bak 's/jessie main/jessie main contrib non-free/g' /etc/apt/sources.list && \
    apt-get update && apt-get install -y \
    chromium \
    chromium-l10n \
    libcanberra-gtk-module \
    libexif-dev \
    libpango1.0-0 \
    libv4l-0 \
    pepperflashplugin-nonfree \                                                                          
    --no-install-recommends && \
    mkdir -p /etc/chromium.d/

# Autorun x11vnc
CMD ["/usr/bin/chromium", "--no-sandbox", "--user-data-dir=/data"]

构建和 运行:

docker build -t chromium
docker run -e DISPLAY=$DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix --privileged chromium

和错误:

[1:1:0202/085603:ERROR:browser_main_loop.cc(164)] Running without the SUID sandbox! See https://code.google.com/p/chromium/wiki/LinuxSUIDSandboxDevelopment for more information on developing with the sandbox on.
No protocol specified
[1:1:0202/085603:ERROR:browser_main_loop.cc(210)] Gtk: cannot open display: :0

我对 Chromium 了解不多,但是,我确实在 X 上工作过 :-) 当你告诉 X 客户端连接到 :0 时,你说的是连接到端口 6000(或无论你的 X 服务器 运行s 是什么)+ 0,或者在这种情况下是端口 6000。事实上,DISPLAY 是 IP:PORT(上面提到的 +6000)。 X 服务器在您的主机上 运行ning,因此,如果您设置:

DISPLAY=your_host_ip:0

这可能行得通。但是,X 服务器不允许来自任何旧客户端的连接,因此,您需要打开您的 X 服务器。在您的主机上,运行

xhost +

在 运行安装 docker 容器之前。所有这一切都假设您可以 运行 在您的主机上使用 chromium(也就是说,您的主机上存在一个 X 服务器)。

尝试

xhost local:root

这解决了我的问题,我在 Debian Jessie 上。 https://github.com/jfrazelle/dockerfiles/issues/4

添加为参考(参见 greg 的真实回答)

在您的 Linux 主机中添加

  xhost +"local:docker@"

在Docker图片中添加

RUN apt-get update
RUN apt-get install -qqy x11-apps

然后是运行

sudo docker run \
    --rm \ # delete container when bash exits
    -it \ # connect TTY
    --privileged \
    --env DISPLAY=unix$DISPLAY \ # export DISPLAY env variable for X server
    -v $XAUTH:/root/.Xauthority \ # provide authority information to X server
    -v /tmp/.X11-unix:/tmp/.X11-unix \ # mount the X11 socket
    -v /home/alex/coding:/coding \
    alexcpn/nvidia-cuda-grpc:1.0 bash

在容器内部-查看示例命令

xclock

因此,我还需要在我的 docker 容器中打开一个图形应用程序。因此,这些是适用于我的环境的步骤。(Docker version: 19.03.12Container OS: Ubuntu 18.04)。 在 运行 连接容器之前,通过 运行 连接此命令使主机的 X 服务器接受来自任何客户端的连接:xhost +。这是一种非常 non-restrictive 的连接到主机 X 服务器的方式,您可以根据给出的其他答案进行限制。然后,运行 带有 --network=host 选项的容器(例如:docker run --network=host <my image name>)。容器启动后,登录其 shell,然后使用 DISPLAY=:0 启动您的应用(例如:DISPLAY=:0 <my graphical app>

所需要的是您的 docker-主机名到外部主机名的别名。当使用仅以 : 开头的 DISPLAY 时,表示本地主机。基本上,您在 docker 内的主机名需要通过 /etc/hosts 解析为与外部主机相同的名称 - 因为这是存储在 .Xauthority

中的名称

对于 Ubuntu 20.04,将 DISPLAY=:0 更改为 DISPLAY=$DISPLAY 为我修复了它,我的本地环境 $DISPLAY 设置为 :1:

docker run --rm -ti --net=host -e DISPLAY=$DISPLAY fr3nd/xeyes

我发现这个脚本可以自动获取你电脑的 ip:

FOR /F "tokens=4 delims= " %%i in ('route print ^| find " 0.0.0.0"') do set localIp=%%i

创建一个 bat 文件并在这个 bat 中放入:

FOR /F "tokens=4 delims= " %%i in ('route print ^| find " 0.0.0.0"') do set 
localIp=%%i
docker run -ti -v /tmp/.X11-unix -v /tmp/.docker.xauth -e 
XAUTHORITY=/tmp/.docker.xauth --net=host -e DISPLAY=%localIp%:0.0 your-container