skip to Main Content

I’m running selenium tests inside a docker container, with Firefox and Geckodriver.
When running that container as root, everything works fine.

When running the container as non-root user (USER 1000), the driver fails to initialize :

[[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)

Relevant parts of my 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

I even added some chmod / chown to try and fix some permissions issues with firefox or 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

And finally the USER instruction to run the container as non-root

USER 1000

I do not manually install selenium. It’s a maven dependency of the project I’m installing where my tests sources are.

6

Answers


  1. According to this MR https://github.com/SeleniumHQ/docker-selenium/pull/485/files#diff-04c6e90faac2675aa89e2176d2eec7d8R43, it may be fixed by add --shm-size 2g when you start the container.

    As the Selenium community provide docker image for Firefox, I think it would be a better choice to use their docker image directly, or create your own based on their dockerfile to reduce the chance of having problem like this.

    Login or Signup to reply.
  2. I met the same issue recently, and tried to solve it by the following

    Message: Failed to read marionette port

    1. in Dockerfile create a directory /.cache
    mkdir -p /.cache;
    

    and give write permission to /.cache directory

    chmod 777 /.cache;
    
    1. if you run docker with specified user id (i.e. Jenkins id), then you need to add some username with the userid and groupid in yourcontainername:/etc/passwd
    echo "somename:x:1234:1235:somename:/tmp:/bin/bash" >> /tmp/passwd 
    

    firefox started

    '/.cache/dconf': Permission denied

    below is my Dockerfile to install geckodriver, copy here for your reference, hopefully it helps!
    #######################################

    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}"
    ###################################################

    Login or Signup to reply.
  3. For me the issue was caused by two identical firefox processes starting when selenium creates the web driver object. It looks like this caused a race condition, preventing the other process from initialising properly.

    To solve this I ran the following commands in the terminal:

    1. List the firefox processes currently running:

      pgrep -laf firefox
      
    2. Kill the identical process (killing the second duplicate process in the list worked for me)

      kill -9 <PID>
      
    Login or Signup to reply.
  4. I was running into the same issue trying to launch a headless Firefox inside a Docker container on Kubernetes. What solved it for me was adding the code below to my Dockerfile

    RUN groupadd ffgroup --gid 2000  
        && useradd ffuser 
        --create-home 
        --home-dir /tmp/ffuser 
        --gid 2000 
        --shell /bin/bash 
        --uid 1000
    

    and then adding the following to the container’s spec:

                securityContext:
                  runAsNonRoot: true
                  runAsUser: 1000
                  runAsGroup: 2000
                  fsGroup: 2000
    
    Login or Signup to reply.
  5. For me, it was a firefox version issue. I was running on Ubuntu 22.04 and the issue was with the snap package of firefox. The solution was to uninstall firefox completely and install the necessary version from the tar file, even apt-get was using snap to install. More detailed info here.

    Login or Signup to reply.
  6. The main problem is .cache and .mozilla folders, which need permissions. The data is generated in the profile of the user who execute the script.

    This solution worked for me:

    1. Identify the user who needs to save the cache. In my case it was
      www-data (the user of Symfony). I checked it in the folder /tmp/.
      You can see the owner of folders like
      /tmp/Temp-276cddf8-d7c5-4a09... These folders are generated by
      Firefox.
    2. The user needs bash permissions, so you have to adjust the file
      /etc/passwd from
      www-data:33:33:www-data:/usr/sbin:/usr/sbin/nologin to www-data:x:33:33:www-data:**/var/www**:**/bin/bash**
    3. Create the folders in the path, in my case is /var/www/ (this path
      is located in the user path specified in the file /etc/passwd).

    mkdir /var/www/.cache

    mkdir /var/www/.mozilla

    chown www-data:www-data .cache

    chown www-data:www-data .mozilla

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search