首页 > 解决方案 > 在带有 windows/servercore 的 Windows 容器上以无头模式运行 Firefox

问题描述

为了提供 Windows Selenium WebDriver Grid,我开始准备允许用作网格节点的 Dockerfile。最初的原因是准备一个带有可控Firefox/GeckoDriver版本的图像。出于相同目的成功准备 Chrome 映像的鼓舞,我从以下 Dockerfile 开始:

FROM mcr.microsoft.com/windows/servercore:1809

# Install chocolatey
RUN @"%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe" -NoProfile -InputFormat None -ExecutionPolicy Bypass -Command "iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))" && SET "PATH=%PATH%;%ALLUSERSPROFILE%\chocolatey\bin"
RUN choco feature enable -n allowGlobalConfirmation

WORKDIR C:\\tools

# Set driver/browser versions
ARG Selenium_Major_Version="3.141"
ARG Selenium_Version="3.141.59"

ARG GeckoDriver_Version="0.24.0"
ARG Firefox_Version="66.0.3"

# Install Java
RUN choco install jdk8

# Download Selenium
RUN powershell Invoke-WebRequest \
    -Uri "https://selenium-release.storage.googleapis.com/$env:Selenium_Major_Version/selenium-server-standalone-$env:Selenium_Version.jar" \
    -OutFile ".\\selenium-server-standalone.jar"

# Install Firefox
RUN choco install firefox --version %Firefox_Version%

COPY config.json .

ENTRYPOINT java \
    -Dwebdriver.gecko.driver=C:\\tools\\geckodriver.exe \
    -jar selenium-server-standalone.jar \
    -role node \
    -nodeConfig config.json

现在,一旦容器启动,WebDriver 中生成的 geckodriver 的响应(使用 TRACE 级别的日志执行)将挂起:

node_1  | 1555088898615 mozrunner::runner       INFO    Running command: "C:\\Program Files\\Mozilla Firefox\\firefox.exe" "-marionette" "--headless" "-foreground" "-no-remote" "-profile" "C:\\Users\\ContainerAdministrator\\AppData\\Local\\Temp\\rust_mozprofile.SfT4FwVW8T8s"
node_1  | 1555088898631 geckodriver::marionette DEBUG   Waiting 60s to connect to browser on 127.0.0.1:49171
node_1  | 1555088959727 mozrunner::runner       DEBUG   Killing process 1252
node_1  | 1555088959727 webdriver::server       DEBUG   <- 500 Internal Server Error {"value":{"error":"unknown error","message":"connection refused","stacktrace":""}}

所以这是一个 Firefox 没有正确启动的问题,因为 GeckoDriver 能够生成它但不能与之交互。此外,直接在容器中运行 firefox.exe 会导致 firefox.exe 进程在tasklist执行后出现,但它只是一个占用 6MB RAM 的进程(不像 Chrome,它会产生数十个进程并且无头运行没有问题,对于在 Windows 10 上执行的 Firefox)。我假设有某种障碍阻止 Firefox 被打开,并且由于 Server Core 没有 GUI,它无法显示并且无法诊断。遗憾的是,我没有找到任何有关存储在磁盘上的 Firefox 日志的信息,也没有从命令行以更详细的模式运行 Firefox。我已经尝试过的事情:

总而言之,即使不可能(但为什么?Chrome 可能),我想知道实际错误是什么以及失败的原因是什么。来自 Firefox 本身的更多详细信息也会很方便。

我知道最简单的方法是切换到 Linux,但长话短说,目前还不可能。

版本:

标签: dockerfirefoxwebdriverserver-corewindows-server-container

解决方案


我认为你正在耗尽你的共享内存(没有看到你如何运行你的 docker,但在猜测)。问题是geckodriver阻塞了共享内存。原因还没有完全弄清楚。你有两个选择。挂载共享内存或设置固定大小。

如果要设置固定大小,请使用--shm-size(共享内存大小)开关。您必须将其设置为至少ShmSize: 1800000000(1.8g)。通常为简单起见将其设置为 2G:

--shm-size 2g

如果您查看 github docs running images,您甚至可以看到以下警告:

❗️ 当使用 Chrome 或 Firefox 为图像执行 docker run 时,请挂载 -v /dev/shm:/dev/shm 或使用标志 --shm-size=2g 来使用主机的共享内存。

对于 Firefox,它将是:

$ docker run -d -p 4444:4444 -v /dev/shm:/dev/shm selenium/standalone-firefox:3.141.59-mercury
OR
$ docker run -d -p 4444:4444 --shm-size 2g selenium/standalone-firefox:3.141.59-mercury

一些人报告说,即使提高限制也无济于事。如果这是你的情况,你可以破解about:config

去引用:

我已经能够通过在退出主选项卡之前关闭选项卡来解决此问题。在关闭之前还将 URL 设置为 about:config/blank,

while (this.WindowHandles.Count > 1)
{
    this.Navigate().GoToUrl("about:config");
    this.Navigate().GoToUrl("about:blank");
    this.Close(); //Close Tab
    this.SwitchTo().Window(this.WindowHandles.Last());
}
this.Navigate().GoToUrl("about:config");
this.Navigate().GoToUrl("about:blank");
this.Quit(); //Then main window

推荐阅读