我正在 Docker 容器内使用 Firefox 和 Geckodriver 运行 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)
我的 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
我什至添加了一些 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
最后是以非 root 身份运行容器的 USER 指令
USER 1000
我不手动安装selenium。这是我正在安装的测试源所在的项目的 Maven 依赖项。
你也可以通过apt安装firefox,这一步为我解决了这个问题。 (https://github.com/FortyNorthSecurity/EyeWitness/issues/604 和 https://www.omgubuntu.co.uk/2022/04/how-to-install-firefox-deb-apt-ubuntu- 22-04)
第 1 步:通过在新的终端窗口中运行以下命令来删除 Firefox Snap:
sudo snap remove firefox
第 2 步:通过在同一终端窗口中运行以下命令,将 (Ubuntu) Mozilla 团队 PPA 添加到您的软件源列表中:
sudo add-apt-repository ppa:mozillateam/ppa
第 3 步:接下来,更改 Firefox 软件包优先级,以确保首选 PPA/deb/apt 版本的 Firefox。这可以使用 FosTips 中的一段代码来完成(整个复制并粘贴,而不是逐行粘贴):
echo '
Package: *
Pin: release o=LP-PPA-mozillateam
Pin-Priority: 1001
' | sudo tee /etc/apt/preferences.d/mozilla-firefox
第 4 步:由于您(希望)希望自动安装未来的 Firefox 升级,Balint Reczey 在他的博客上分享了一个简洁的命令,以确保它发生:
echo 'Unattended-Upgrade::Allowed-Origins:: "LP-PPA-mozillateam:${distro_codename}";' | sudo tee /etc/apt/apt.conf.d/51unattended-upgrades-firefox
第 5 步:最后,运行以下命令通过 apt 安装 Firefox:
sudo apt install firefox
我最近遇到了同样的问题,并尝试通过以下方式解决它
/.cache
mkdir -p /.cache;\
并给予
/.cache
目录写权限
chmod 777 /.cache;\
yourcontainername:/etc/passwd
echo "somename:x:1234:1235:somename:/tmp:/bin/bash" >> /tmp/passwd
下面是我安装geckodriver的Dockerfile,复制到这里供大家参考,希望对您有帮助! #########################################
RUN (install_dir="/opt/automation/data/webdriver"; \
url=$(curl -s https://api.github.com/repos/mozilla/geckodriver/releases/latest | python -c "import sys, json; print(next(item['browser_download_url'] for item in json.load(sys.stdin)['assets'] if 'linux64' in item.get('browser_download_url', '')))"); \
echo "url $url"; \
wget -O geckodriver.tar.gz "$url"; \
tar -xvzf geckodriver.tar.gz -C $install_dir; \
chmod 777 $install_dir/geckodriver;\
ls -la $install_dir;\
ln -s $install_dir/geckodriver /usr/local/bin/geckodriver;\
chmod 777 /usr/local/bin/geckodriver;\
chown root:root $install_dir/geckodriver;\
chown root:root /usr/local/bin/geckodriver;\
mkdir -p /.cache;\
chmod 777 /.cache;\
ls -la /.cache;\
export PATH=$PATH:$install_dir;\
mkdir $HOME/tmp;\
export TMPDIR=$HOME/tmp geckodriver;\
echo "seleniumuser:x:idxxx:group_idxxx:seleniumuser:/tmp:/bin/bash" >> /etc/passwd;\
echo "installed geckodriver binary in $install_dir";)
ENV PATH="/opt/automation/data/webdriver:${PATH}"
################################################## ##
对我来说,这是一个 Firefox 版本问题。我在 Ubuntu 22.04 上运行,问题出在 Firefox 的 snap 包上。解决方案是完全卸载firefox并从tar文件中安装必要的版本,甚至apt-get也是使用snap来安装的。更多详细信息这里。
主要问题是
.cache
和.mozilla
文件夹,它们需要权限。数据在执行脚本的用户的个人资料中生成。
这个解决方案对我有用:
/tmp/
中检查过它。
您可以看到文件夹的所有者,例如
/tmp/Temp-276cddf8-d7c5-4a09...
这些文件夹是由
火狐浏览器。/etc/passwd
来自
www-data:33:33:www-data:/usr/sbin:/usr/sbin/nologin
至 www-data:x:33:33:www-data:**/var/www**:**/bin/bash**
/var/www/
(这个路径
位于文件中指定的用户路径/etc/passwd
)。mkdir /var/www/.cache
mkdir /var/www/.mozilla
chown www-data:www-data .cache
chown www-data:www-data .mozilla
根据这个MR https://github.com/SeleniumHQ/docker-selenium/pull/485/files#diff-04c6e90faac2675aa89e2176d2eec7d8R43,启动容器时可以通过添加
--shm-size 2g
来修复。
由于 Selenium 社区为 Firefox 提供了 docker 镜像,我认为直接使用他们的 docker 镜像,或者基于他们的 dockerfile 创建自己的镜像会是更好的选择,以减少出现此类问题的机会。
对我来说,这个问题是由 selenium 创建 Web 驱动程序对象时启动的两个相同的 Firefox 进程引起的。看起来这导致了竞争条件,导致其他进程无法正确初始化。
为了解决这个问题,我在终端中运行了以下命令:
列出当前正在运行的 Firefox 进程:
pgrep -laf firefox
终止相同的进程(终止列表中的第二个重复进程对我有用)
kill -9 <PID>
我在尝试在 Kubernetes 上的 Docker 容器内启动无头 Firefox 时遇到了同样的问题。对我来说解决这个问题的方法是将下面的代码添加到我的
Dockerfile
RUN groupadd ffgroup --gid 2000 \
&& useradd ffuser \
--create-home \
--home-dir /tmp/ffuser \
--gid 2000 \
--shell /bin/bash \
--uid 1000
然后将以下内容添加到容器的规格中:
securityContext:
runAsNonRoot: true
runAsUser: 1000
runAsGroup: 2000
fsGroup: 2000