在 Docker 容器中以非 root 用户身份运行 Selenium + geckodriver + firefox 时“无法读取 marionette 端口”

Gui*_*ges 10 firefox selenium docker geckodriver

我正在使用 Firefox 和 Geckodriver 在 docker 容器内运行 selenium 测试。当以 root 身份运行该容器时,一切正常。

当以非 root 用户 (USER 1000) 运行容器时,驱动程序无法初始化:

[[1;31mERROR[m] test01_WO_default_dashboard  Time elapsed: 132.6 s  <<< ERROR!
org.openqa.selenium.TimeoutException: 
Failed to read marionette port
Build info: version: '3.14.0', revision: 'aacccce0', time: '2018-08-02T20:19:58.91Z'
System info: host: 'testrunner-cockpit-3--1-mdbwj', ip: '10.130.2.18', os.name: 'Linux', os.arch: 'amd64', os.version: '4.18.0-305.28.1.el8_4.x86_64', java.version: '11.0.15'
Driver info: driver.version: FirefoxDriver
remote stacktrace: 
    at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490)
    at org.openqa.selenium.remote.W3CHandshakeResponse.lambda$new$0(W3CHandshakeResponse.java:57)
    at org.openqa.selenium.remote.W3CHandshakeResponse.lambda$getResponseFunction$2(W3CHandshakeResponse.java:104)
    at org.openqa.selenium.remote.ProtocolHandshake.lambda$createSession$0(ProtocolHandshake.java:122)
    at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195)
    at java.base/java.util.Spliterators$ArraySpliterator.tryAdvance(Spliterators.java:958)
    at java.base/java.util.stream.ReferencePipeline.forEachWithCancel(ReferencePipeline.java:127)
    at java.base/java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:502)
    at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:488)
    at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
    at java.base/java.util.stream.FindOps$FindOp.evaluateSequential(FindOps.java:150)
    at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
    at java.base/java.util.stream.ReferencePipeline.findFirst(ReferencePipeline.java:543)
    at org.openqa.selenium.remote.ProtocolHandshake.createSession(ProtocolHandshake.java:125)
    at org.openqa.selenium.remote.ProtocolHandshake.createSession(ProtocolHandshake.java:73)
    at org.openqa.selenium.remote.HttpCommandExecutor.execute(HttpCommandExecutor.java:136)
    at org.openqa.selenium.remote.service.DriverCommandExecutor.execute(DriverCommandExecutor.java:83)
    at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:548)
    at org.openqa.selenium.remote.RemoteWebDriver.startSession(RemoteWebDriver.java:212)
    at org.openqa.selenium.remote.RemoteWebDriver.<init>(RemoteWebDriver.java:130)
    at org.openqa.selenium.firefox.FirefoxDriver.<init>(FirefoxDriver.java:125)
Run Code Online (Sandbox Code Playgroud)

我的 Dockerfile 的相关部分:

FROM ubuntu:20.04

# install firefox
ARG FIREFOX_VERSION=latest
RUN FIREFOX_DOWNLOAD_URL=$(if [ $FIREFOX_VERSION = "latest" ] || [ $FIREFOX_VERSION = "nightly-latest" ] || [ $FIREFOX_VERSION = "devedition-latest" ] || [ $FIREFOX_VERSION = "esr-latest" ]; then echo "https://download.mozilla.org/?product=firefox-$FIREFOX_VERSION-ssl&os=linux64&lang=en-US"; else echo "https://download-installer.cdn.mozilla.net/pub/firefox/releases/$FIREFOX_VERSION/linux-x86_64/en-US/firefox-$FIREFOX_VERSION.tar.bz2"; fi) \
  && apt-get update -qqy \
  && apt-get -qqy --no-install-recommends install firefox libavcodec-extra \
  && rm -rf /var/lib/apt/lists/* /var/cache/apt/* \
  && wget --no-verbose -O /tmp/firefox.tar.bz2 $FIREFOX_DOWNLOAD_URL \
  && apt-get -y purge firefox \
  && rm -rf /opt/firefox \
  && tar -C /opt -xjf /tmp/firefox.tar.bz2 \
  && rm /tmp/firefox.tar.bz2 \
  && mv /opt/firefox /opt/firefox-$FIREFOX_VERSION \
  && ln -fs /opt/firefox-$FIREFOX_VERSION/firefox /usr/bin/firefox

# install geckodriver
ARG GECKODRIVER_VERSION=latest
RUN GK_VERSION=$(if [ ${GECKODRIVER_VERSION:-latest} = "latest" ]; then echo "0.31.0"; else echo $GECKODRIVER_VERSION; fi) \
  && echo "Using GeckoDriver version: "$GK_VERSION \
  && wget --no-verbose -O /tmp/geckodriver.tar.gz https://github.com/mozilla/geckodriver/releases/download/v$GK_VERSION/geckodriver-v$GK_VERSION-linux64.tar.gz \
  && rm -rf /opt/geckodriver \
  && tar -C /opt -zxf /tmp/geckodriver.tar.gz \
  && rm /tmp/geckodriver.tar.gz \
  && mv /opt/geckodriver /opt/geckodriver-$GK_VERSION \
  && chmod 755 /opt/geckodriver-$GK_VERSION \
  && ln -fs /opt/geckodriver-$GK_VERSION /usr/bin/geckodriver \
  && geckodriver --version
Run Code Online (Sandbox Code Playgroud)

我什至添加了一些 chmod / chown 来尝试修复 firefox 或 geckodriver 的一些权限问题:

RUN chown 1000 -R /usr/bin/geckodriver \
 && chmod 775 -R /usr/bin/geckodriver \
 && chown 1000 -R /usr/bin/firefox \
 && chmod 775 -R /usr/bin/firefox
Run Code Online (Sandbox Code Playgroud)

最后是 USER 指令以非 root 身份运行容器

USER 1000
Run Code Online (Sandbox Code Playgroud)

我不手动安装selenium。这是我正在安装的测试源所在的项目的 Maven 依赖项。

小智 15

您也可以通过 apt 安装 Firefox,这一步为我解决了这个问题。(https://github.com/FortyNorthSecurity/EyeWitness/issues/604https://www.omgubuntu.co.uk/2022/04/how-to-install-firefox-deb-apt-ubuntu-22-04

\n

步骤 1:通过在新的终端窗口中运行以下命令来删除 Firefox Snap:

\n
sudo snap remove firefox\n
Run Code Online (Sandbox Code Playgroud)\n

步骤 2:通过在同一终端窗口中运行以下命令,将 (Ubuntu) Mozilla 团队 PPA 添加到您的软件源列表中:

\n
sudo add-apt-repository ppa:mozillateam/ppa\n
Run Code Online (Sandbox Code Playgroud)\n

步骤 3:接下来,更改 Firefox 软件包优先级,以确保首选 PPA/deb/apt 版本的 Firefox。这可以使用 FosTips 中的一段代码来完成(整个复制并粘贴,而不是逐行粘贴):

\n
echo \'\nPackage: *\nPin: release o=LP-PPA-mozillateam\nPin-Priority: 1001\n\' | sudo tee /etc/apt/preferences.d/mozilla-firefox\n
Run Code Online (Sandbox Code Playgroud)\n

步骤 4:由于您\xe2\x80\x99ll(希望)希望自动安装未来的 Firefox 升级,Balint Reczey 在他的博客上分享了一个简洁的命令,以确保它发生:

\n
echo \'Unattended-Upgrade::Allowed-Origins:: "LP-PPA-mozillateam:${distro_codename}";\' | sudo tee /etc/apt/apt.conf.d/51unattended-upgrades-firefox\n
Run Code Online (Sandbox Code Playgroud)\n

第 5 步:最后,运行以下命令通过 apt 安装 Firefox:

\n
sudo apt install firefox\n
Run Code Online (Sandbox Code Playgroud)\n


lin*_*k89 0

根据这个MR https://github.com/SeleniumHQ/docker-selenium/pull/485/files#diff-04c6e90faac2675aa89e2176d2eec7d8R43 --shm-size 2g ,启动容器时可能会通过add修复。

由于 Selenium 社区为 Firefox 提供了 docker 镜像,我认为直接使用他们的 docker 镜像,或者基于他们的 dockerfile 创建自己的镜像会是更好的选择,以减少出现此类问题的机会。