如何在Docker中运行Google Chrome的无头(Headless)模式?

61

我的问题是如何在 Docker 容器中运行 Google Chrome 进行端到端测试。 我从官方 Jenkins 镜像创建了一个 Dockerfile,但当尝试运行 Google Chrome 时,它会崩溃并显示错误:

Failed to move to new namespace: PID namespaces supported, Network namespace supported, but failed: errno = Operation not permitted
Trace/breakpoint trap (core dumped)

Jenkins的Docker镜像使用Debian jessie

我可以使用--headless标志运行Google Chrome,不需要X服务器。

这是我的Docker文件:

Jenkins官方镜像:

有人在Docker中使用GUI运行Google Chrome的存储库:

我的第一个尝试是使用xvbf,但是当使用--headless标志时,该过程更简单。

我可以使用相同的安装命令在Ubuntu服务器上运行Chrome,但在Docker中失败。

在尝试其他方法后,我使用了--no-sandbox标志,但Docker镜像显示以下错误。

[0427/180929.595479:WARNING:audio_manager.cc(295)] Multiple instances of AudioManager detected
[0427/180929.595537:WARNING:audio_manager.cc(254)] Multiple instances of AudioManager detected
libudev: udev_has_devtmpfs: name_to_handle_at on /dev: Operation not permitted

实际上我运行了这个命令:

google-chrome-stable --headless --disable-gpu --no-sandbox http://www.google.com


1
特别是现在google-chrome-beta(版本59)发布了,我非常希望拥有它。我尝试过让它运行起来,但遇到了同样的问题。 - Ghazgkull
你尝试过在运行时添加这些标志吗?google-chrome-unstable --disable-gpu --headless --user-data-dir=/var/jenkins_home/chrome-data - Vova Rozhkov
这是我如何在Docker中运行C#应用程序和Selenium的方法:其他问题,相同答案 - Michael Santos
6个回答

12

只需使用--no-sandbox参数启动Chrome即可解决该问题。


6
这可能是一个严重的安全问题。这篇简单的文章解释了原因。这第二篇文章详细地解释了为什么会出现这种情况 - Cyril N.
2
你可以尝试使用自定义的 seccomp,而不是 --no-sandbox。请参考这里 - usethe4ce
2
只是出于好奇 @CyrilN. ... 如果您正在Docker实例中运行Chrome,这是一种沙盒,那么 --no-sandbox 参数不就变得无用了吗? - JwJosefy
2
@JwJosefy 或许吧,我不是 Docker 专家。我认为这取决于您在 Docker 实例上运行的其他内容。如果只是 Chrome,那么我会说是的,但要谨慎对待。 - Cyril N.
1
那篇第二篇文章并没有解释为什么这是一个安全问题,而只是解释了沙盒是什么以及其目的。没有足够的上下文来暗示这在根本上是不安全的。 - Chris Stryczynski

10

我在Ubuntu中使用这个镜像alpeware/chrome-headless-trunk,成功运行了Headless Chrome。 在该容器中启动Headless Chrome的命令如下:

/usr/bin/google-chrome-unstable \
--disable-gpu --headless --no-sandbox \
--remote-debugging-address=0.0.0.0 \
--remote-debugging-port=9222 --user-data-dir=/data

这是容器运行的短视频:chrome headless in action

我在Ubuntu中使用以下命令启动了容器:

 docker run -it --rm -p=0.0.0.0:9222:9222 \ 
 --name=chrome-headless \
 -v /tmp/chromedata/:/data alpeware/chrome-headless-trunk

然后使用 Chrome 连接到调试端口 localhost:9222

经过一些修改,你可能可以让它在Jenkins中运行!

来源


1
你为什么要添加“--disable-gpu”呢? - Gajus
3
--no-sandbox = 极大的安全问题。 - Merc
5
是的,这是一个已知的安全问题。您是否有一个示例可以分享,该示例不使用 --no-sandbox 参数? - kongkoro
GitHub仓库自2021年8月14日以来已经过时。 - Paul Verest

4

这已经在这个答案中说过了。 - Adrian W
4
这是一个巨大的安全问题。 - Cyril N.

3

GitHub仓库自2018年1月22日以来已经过时。 - Paul Verest

2

1
你使用哪个测试库?我尝试使用mochawebdriver.io进行设置,但是当我尝试从浏览器获取值时,总是出现“Error: A session id is required for this command but wasn't found in the response payload”的错误。 - Gobliins

1

我通过以下方式扩展默认的Dockerfile Selenium Chrome Node

FROM selenium/standalone-chrome-debug:latest
MAINTAINER Serge Arbuzov <Serge.Arbuzov@advantechwireless.com>

USER root

### jenkins set up ###
RUN apt-get update && apt-get install -y openssh-server sudo
RUN mkdir /var/run/sshd
RUN adduser jenkins
RUN echo jenkins:jenkins | chpasswd
RUN echo "jenkins ALL=(ALL) NOPASSWD:ALL">>/etc/sudoers

USER root
RUN echo export DISPLAY=":1.5" >> /etc/environment
ADD run.sh /run.sh
RUN chmod +x /run.sh

EXPOSE 22

CMD ["/run.sh"]

我的 run.sh 文件内容如下:

#!/bin/bash

Xvfb :1 -screen 5 1024x768x8 &
/usr/sbin/sshd -D

所以我可以使用默认图像作为Jenkins节点


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接