Search code examples
javadockerseleniumdockerfilegeckodriver

Selenium inside Docker image for Java application


I've developped Java application to make some litle web scraping tasks with Selenium. It work fine in my local environment with Windows 10 and both chrome / FireFox last versions with their appropriate driver path configured.

The thing is I need my application to be in a container to deploy it and I've got issues. I've created a Dockerfile based on Alpine, and installed what need to be installed (helped by some posts found on the internet). With the FireFox driver it's working almost fine for the first operations but some do not work the same as they do in my configuration in local and some even crash the client... That's why I've tried with chromium but I've got some issues with a connection to the browser not even working.

I've spent hours already on this and start thinking maybe I'm missing something, am I supposed to do that way by dowloading browsers and driver in my Dockerfile ?

For now I sucpect the versions of FireFox or the geckodriver associated not behaving the same as the one I've got on my machine and I can see the browser when It's working inside the container only logs I've added.

Dockerfile (for FireFox browser try) :

FROM openjdk:8-jdk-alpine
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} app.jar

# https://stackoverflow.com/questions/58738920/running-geckodriver-in-an-alpine-docker-container
# Get all the prereqs
RUN wget -q -O /etc/apk/keys/sgerrand.rsa.pub https://alpine-pkgs.sgerrand.com/sgerrand.rsa.pub
RUN wget https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.34-r0/glibc-2.34-r0.apk
RUN wget https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.34-r0/glibc-bin-2.34-r0.apk
RUN apk add glibc-2.34-r0.apk
RUN apk add glibc-bin-2.34-r0.apk

# And of course we need Firefox if we actually want to *use* GeckoDriver
RUN apk add firefox-esr=60.9.0-r0

# Then install GeckoDriver
RUN wget https://github.com/mozilla/geckodriver/releases/download/v0.29.1/geckodriver-v0.29.1-linux64.tar.gz
RUN tar -zxf geckodriver-v0.29.1-linux64.tar.gz -C /usr/bin

ENTRYPOINT ["java","-jar","/app.jar"]

Dockerfile (for Chrome browser try, I know optimisations could be made probably) :

FROM openjdk:8-jdk-alpine
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} app.jar

RUN apk update && apk add --no-cache bash \
    alsa-lib \
    at-spi2-atk \
    atk \
    cairo \
    cups-libs \
    dbus-libs \
    eudev-libs \
    expat \
    flac \
    gdk-pixbuf \
    glib \
    libgcc \
    libjpeg-turbo \
    libpng \
    libwebp \
    libx11 \
    libxcomposite \
    libxdamage \
    libxext \
    libxfixes \
    tzdata \
    libexif \
    udev \
    xvfb \
    zlib-dev \
    chromium \
    chromium-chromedriver

ENTRYPOINT ["java","-jar","/app.jar"]

Maybe I should use a docker image like https://hub.docker.com/r/selenium/standalone-firefox and install Java manually instead ?

I'm very frustrated by could not being able to reproduce my local behavior inside the container and I would really appreciate some help on this ! I don't want to give up :)


Solution

  • Indeed Jortega I've based my image on the selenium image : https://hub.docker.com/r/selenium/standalone-firefox

    Here is my Dockerfile

    FROM selenium/standalone-firefox:91.0-20210823
    ARG JAR_FILE=target/*.jar
    COPY ${JAR_FILE} app.jar
    
    # Spring boot entrypoint
    ENTRYPOINT ["java","-jar","/app.jar"]
    

    In my Java application here's the FireFox configuration :

    // webBrowserDriverPath is a env variable set to "/usr/bin/geckodriver"
    System.setProperty("webdriver.gecko.driver", webBrowserDriverPath);
    final FirefoxOptions options = new FirefoxOptions();
    options.addArguments(
                "--no-sandbox",
                "--disable-extensions",
                "--disable-gpu",
                "--window-size=1920,1200",
                "--ignore-certificate-errors",
                "--whitelisted-ips=''",
                "--disable-dev-shm-usage",
                "--window-size=1920,1080",
                "--lang=fr");
    // display browser in dev mode
    if (conf.isHeadlessModeEnabled()) {
        options.addArguments("--headless");
    }
    options.addPreference("intl.accept_languages", "fr");
    this.remoteWebDriver = new FirefoxDriver(options);
    

    Everything work fine !