'Docker compose wont start selenium grid

I have the following docker compose file

version: "3"

services:
  selenium-hub:
    image: selenium/hub
    container_name: selenium-hub
    ports:
      - "4444:4444"
  chrome:
    image: selenium/node-chrome
    depends_on:
      - selenium-hub
    environment:
      - HUB_PORT_4444_TCP_ADDR=selenium-hub
      - HUB_PORT_4444_TCP_PORT=4444
  firefox:
    image: selenium/node-firefox
    depends_on:
      - selenium-hub
    environment:
      - HUB_PORT_4444_TCP_ADDR=selenium-hub
      - HUB_PORT_4444_TCP_PORT=4444
  devenv:
    build: .
    ports:
      - "4444:4444"

When I run the docker compose file without:
  devenv:
    build: .
    ports:
      - "4444:4444"

It works fine and selenium grid will succefully stand up. When I introduce this service however, the grid wont stand up, the tests will attempt to run but of course there is no grid so it will then fail.

Can you please advise as to where Im going wrong?

Docker file called at build .

FROM maven
RUN apt update
COPY . /

RUN mvn clean test

error message: org.openqa.selenium.remote.UnreachableBrowserException: Could not start a new session. Possible causes are invalid address of the remote server or browser start-up failure.



Solution 1:[1]

I would suggest you follow the below steps -

Prerequisite:

  • Java-8
  • Docker Desktop client
  • UI Test Project

Let's assume your Test Project uses TestNG to run its selenium scripts.

Step 1: Modify your BaseTest or Test starter class to initialize RemoteWebDriver.

Replace or add the below code to your BaseTest or wherever your Browser Driver initialization happens.

 @BeforeTest
  public void beforeTestSetup() throws MalformedURLException {

    MutableCapabilities dc = new ChromeOptions();

    host = System.getenv("HUB_HOST") != null ? System.getenv("HUB_HOST") : "hub";

    driver.set(new RemoteWebDriver(new URL("http://" + host + ":4444/wd/hub"), dc));

    logger.info("Remote Chrome Driver Started...");

    driver.get().manage().deleteAllCookies();
    driver.get().manage().window().maximize();

    }

Step 2: Add Maven Plugins to your pom.xml to create executable jars.

We will need to add the below plugins in order to generate an executable jar for our Test Project.

  • maven-compiler-plugin
  • maven-dependency-plugin
  • maven-jar-plugin

View the below snippet for example -

<build>
  <finalName>dockerized</finalName>
  <plugins>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-compiler-plugin</artifactId>
      <version>3.5.1</version>
      <configuration>
        <compilerVersion>1.8</compilerVersion>
        <source>1.8</source>
        <target>1.8</target>
      </configuration>
    </plugin>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-dependency-plugin</artifactId>
      <executions>
        <execution>
          <id>copy-dependencies</id>
          <phase>prepare-package</phase>
          <goals>
            <goal>copy-dependencies</goal>
          </goals>
          <configuration>
            <outputDirectory>
              ${project.build.directory}/libs
            </outputDirectory>
          </configuration>
        </execution>
      </executions>
    </plugin>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-jar-plugin</artifactId>
      <version>3.1.0</version>
      <executions>
        <execution>
          <goals>
            <goal>test-jar</goal>
          </goals>
        </execution>
      </executions>
    </plugin>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-surefire-plugin</artifactId>
      <version>2.18.1</version>
      <configuration>
        <suiteXmlFiles>
          <suiteXmlFile>testng.xml</suiteXmlFile>
        </suiteXmlFiles>
        <argLine>
          -javaagent:"${settings.localRepository}/org/aspectj/aspectjweaver/${aspectj.version}/aspectjweaver-${aspectj.version}.jar"
        </argLine>
      </configuration>
    </plugin>
  </plugins>
</build>

Step 3: Add a healthcheck.sh script

The healthcheck script is needed to check the Grid availability to receive test requests before running our tests.

echo "Checking if hub is ready - $HUB_HOST"

while [ "$( curl -s http://$HUB_HOST:4444/wd/hub/status | jq -r .value.ready )" != "true" ]
do
    sleep 1
done

Step 4: Add a run.sh script

java -cp dockerized.jar:dockerized-tests.jar:libs/* org.testng.TestNG testng.xml

Step 5: Create a docker-compose.yml file

version: "3"
services:
  hub:
    image: selenium/hub:4.1.3
    ports:
      - "4442:4442"
      - "4443:4443"
      - "4444:4444"

  chrome:
    image: selenium/node-chrome:4.1.3
    shm_size: '3gb'
    depends_on:
      - hub
    links:
      - hub
    environment:
      - SE_EVENT_BUS_HOST=hub
      - SE_EVENT_BUS_PUBLISH_PORT=4442
      - SE_EVENT_BUS_SUBSCRIBE_PORT=4443
      - VNC_NO_PASSWORD=1

  test-run:
    build: .
    container_name: test-run
    depends_on:
      - chrome
    links:
      - hub
    environment:
      - MODULE=testng.xml
    volumes:
      - ./src/test/resources/results:/app

Step 6: Create a Dockerfile to instruct the creation of your Docker Image

We will use multiple base images in multi-stage builds to create the final image. The first stage (named package) will generate the executable jars and the second stage (named testrun) will run these executable jars.

Do note the different base images being used in each stage as required.

FROM maven:3.6.1-jdk-8-alpine AS package

RUN apk add --update \
    curl \
    jq

RUN mkdir -p /app
WORKDIR /app

COPY pom.xml                          .
COPY healthcheck.sh                   .
RUN mvn -e -B dependency:resolve

COPY src                              ./src
RUN mvn verify --fail-never -DskipTests

WORKDIR /app/

ENTRYPOINT ["/bin/sh"]
CMD ["healthcheck.sh"]

FROM openjdk:8-jre-alpine AS testrun

RUN mkdir -p /jar
WORKDIR /jar/

COPY --from=package /app/target/dockerized.jar         .
COPY --from=package /app/target/dockerized-tests.jar   .
COPY --from=package /app/target/libs                        ./libs
COPY testng.xml                                             .
COPY run.sh                                                 .

WORKDIR /jar/

ENV HUB_HOST=hub
ENV MODULE=testng.xml

ENTRYPOINT ["/bin/sh"]
CMD ["run.sh"]

Step 7: Finally, run your docker-compose

Open Powershell in your project root folder and run the below command.

***docker-compose up --build***

Sample Project Link - https://gitlab.com/suryajit7/my-blog-topics

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Uchiha Suryajit